Skip to content

Commit

Permalink
When presentation mode chosen by user in SurfaceTraits structure is n…
Browse files Browse the repository at this point in the history
…ot available on GPU, then Surface class tries to choose most appropriate presentation mode itself. It shows warning about this change to the user.

Also - added static variables storing presentation mode names, so that it's not necessary to declare these names in main().
This is commit number 200 and the first one that resolves github issue. I'll be on vacation until 1 September.
  • Loading branch information
pumexx committed Aug 14, 2018
1 parent 0d1fbed commit ab7e47b
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 49 deletions.
9 changes: 1 addition & 8 deletions examples/pumexcrowd/pumexcrowd.cpp
Expand Up @@ -589,18 +589,11 @@ int main(int argc, char * argv[])
{
SET_LOG_INFO;

std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
args::ArgumentParser parser("pumex example : multithreaded crowd rendering on more than one window");
args::HelpFlag help(parser, "help", "display this help menu", {'h', "help"});
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", {'d'});
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", {'f'});
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
args::Flag renderVRwindows(parser, "vrwindows", "create two halfscreen windows for VR", { 'v' });
args::Flag render3windows(parser, "three_windows", "render in three windows", {'t'});
Expand Down
9 changes: 1 addition & 8 deletions examples/pumexdeferred/pumexdeferred.cpp
Expand Up @@ -197,13 +197,6 @@ int main( int argc, char * argv[] )
{
SET_LOG_INFO;

std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
std::unordered_map<std::string, VkSampleCountFlagBits> availableSamplesPerPixel
{
{ "1", VK_SAMPLE_COUNT_1_BIT },
Expand All @@ -216,7 +209,7 @@ int main( int argc, char * argv[] )
args::HelpFlag help(parser, "help", "display this help menu", { 'h', "help" });
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", { 'd' });
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", { 'f' });
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
args::Flag skipDepthPrepass(parser, "nodp", "skip depth prepass", { 'n' });
args::MapFlag<std::string, VkSampleCountFlagBits> samplesPerPixel(parser, "samples", "samples per pixel (1,2,4,8)", { 's' }, availableSamplesPerPixel, VK_SAMPLE_COUNT_4_BIT);
Expand Down
9 changes: 1 addition & 8 deletions examples/pumexgpucull/pumexgpucull.cpp
Expand Up @@ -1230,18 +1230,11 @@ int main(int argc, char * argv[])
{
SET_LOG_INFO;

std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
args::ArgumentParser parser("pumex example : instanced rendering for static and dynamic objects");
args::HelpFlag help(parser, "help", "display this help menu", { 'h', "help" });
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", { 'd' });
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", { 'f' });
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
args::Flag renderVRwindows(parser, "vrwindows", "create two halfscreen windows for VR", { 'v' });
args::Flag render3windows(parser, "three_windows", "render in three windows", { 't' });
Expand Down
9 changes: 1 addition & 8 deletions examples/pumexmultiview/pumexmultiview.cpp
Expand Up @@ -234,18 +234,11 @@ int main( int argc, char * argv[] )
{
SET_LOG_INFO;

std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
args::ArgumentParser parser("pumex example : multiview deferred rendering with PBR and antialiasing");
args::HelpFlag help(parser, "help", "display this help menu", { 'h', "help" });
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", { 'd' });
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", { 'f' });
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
try
{
Expand Down
11 changes: 2 additions & 9 deletions examples/pumexviewer/pumexviewer.cpp
Expand Up @@ -140,18 +140,11 @@ int main( int argc, char * argv[] )
SET_LOG_INFO;

// process command line using args library
std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
args::ArgumentParser parser("pumex example : minimal 3D model viewer without textures");
args::HelpFlag help(parser, "help", "display this help menu", { 'h', "help" });
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", { 'd' });
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", { 'f' });
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
args::Positional<std::string> modelNameArg(parser, "model", "3D model filename");
args::Positional<std::string> animationNameArg(parser, "animation", "3D model with animation");
Expand Down Expand Up @@ -418,4 +411,4 @@ int main( int argc, char * argv[] )
viewer->cleanup();
FLUSH_LOG;
return 0;
}
}
9 changes: 1 addition & 8 deletions examples/pumexvoxelizer/pumexvoxelizer.cpp
Expand Up @@ -184,18 +184,11 @@ int main( int argc, char * argv[] )
{
SET_LOG_INFO;

std::unordered_map<std::string, VkPresentModeKHR> availablePresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};
args::ArgumentParser parser("pumex example : model voxelization and rendering");
args::HelpFlag help(parser, "help", "display this help menu", { 'h', "help" });
args::Flag enableDebugging(parser, "debug", "enable Vulkan debugging", { 'd' });
args::Flag useFullScreen(parser, "fullscreen", "create fullscreen window", { 'f' });
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::MapFlag<std::string, VkPresentModeKHR> presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR);
args::ValueFlag<uint32_t> updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60);
args::Positional<std::string> modelNameArg(parser, "model", "3D model filename" );
args::Positional<std::string> animationNameArg(parser, "animation", "3D model with animation");
Expand Down
6 changes: 6 additions & 0 deletions include/pumex/Surface.h
Expand Up @@ -24,6 +24,7 @@
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <vulkan/vulkan.h>
#include <pumex/Export.h>
#include <pumex/Device.h>
Expand Down Expand Up @@ -182,6 +183,11 @@ class PUMEX_EXPORT Surface : public std::enable_shared_from_this<Surface>

void createSwapChain();
bool checkWorkflow();

public:
static const std::unordered_map<std::string, VkPresentModeKHR> nameToPresentationModes;
static const std::unordered_map<VkPresentModeKHR, std::string> presentationModeNames;
static const std::unordered_map<VkPresentModeKHR, std::vector<VkPresentModeKHR>> replacementModes;
};

bool Surface::isRealized() const { return realized; }
Expand Down
50 changes: 50 additions & 0 deletions src/pumex/Surface.cpp
Expand Up @@ -41,6 +41,31 @@ SurfaceTraits::SurfaceTraits(uint32_t ic, VkColorSpaceKHR ics, uint32_t ial, VkP
{
}

const std::unordered_map<std::string, VkPresentModeKHR> Surface::nameToPresentationModes
{
{ "immediate", VK_PRESENT_MODE_IMMEDIATE_KHR },
{ "mailbox", VK_PRESENT_MODE_MAILBOX_KHR },
{ "fifo", VK_PRESENT_MODE_FIFO_KHR },
{ "fifo_relaxed", VK_PRESENT_MODE_FIFO_RELAXED_KHR }
};

const std::unordered_map<VkPresentModeKHR, std::string> Surface::presentationModeNames
{
{ VK_PRESENT_MODE_IMMEDIATE_KHR, "immediate" },
{ VK_PRESENT_MODE_MAILBOX_KHR, "mailbox" },
{ VK_PRESENT_MODE_FIFO_KHR, "fifo" },
{ VK_PRESENT_MODE_FIFO_RELAXED_KHR, "fifo_relaxed" }
};

const std::unordered_map<VkPresentModeKHR, std::vector<VkPresentModeKHR>> Surface::replacementModes
{
{ VK_PRESENT_MODE_IMMEDIATE_KHR,{ VK_PRESENT_MODE_MAILBOX_KHR , VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR } },
{ VK_PRESENT_MODE_MAILBOX_KHR,{ VK_PRESENT_MODE_IMMEDIATE_KHR , VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR } },
{ VK_PRESENT_MODE_FIFO_KHR,{ VK_PRESENT_MODE_FIFO_RELAXED_KHR , VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR } },
{ VK_PRESENT_MODE_FIFO_RELAXED_KHR,{ VK_PRESENT_MODE_FIFO_KHR , VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR } }
};


Surface::Surface(std::shared_ptr<Viewer> v, std::shared_ptr<Window> w, std::shared_ptr<Device> d, VkSurfaceKHR s, const SurfaceTraits& st)
: viewer{ v }, window{ w }, device{ d }, surface{ s }, surfaceTraits(st)
{
Expand Down Expand Up @@ -79,12 +104,37 @@ void Surface::realize()

// collect surface properties
VK_CHECK_LOG_THROW( vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phDev, surface, &surfaceCapabilities), "failed vkGetPhysicalDeviceSurfaceCapabilitiesKHR for surface " << getID() );

// collect available presentation modes
uint32_t presentModeCount;
VK_CHECK_LOG_THROW( vkGetPhysicalDeviceSurfacePresentModesKHR(phDev, surface, &presentModeCount, nullptr), "Could not get present modes for surface " << getID());
CHECK_LOG_THROW( presentModeCount == 0, "No present modes defined for this surface" );
presentModes.resize(presentModeCount);
VK_CHECK_LOG_THROW( vkGetPhysicalDeviceSurfacePresentModesKHR(phDev, surface, &presentModeCount, presentModes.data()), "Could not get present modes " << presentModeCount << " for surface " << getID());

// check if presentation mode from surface traits is available
auto presentIt = std::find(begin(presentModes), end(presentModes), surfaceTraits.swapchainPresentMode);
if (presentIt == end(presentModes))
{
// presentation mode from surface traits is not available. Choose the most appropriate one and inform user about the change

auto prefIt = replacementModes.find(surfaceTraits.swapchainPresentMode);
CHECK_LOG_THROW(prefIt == end(replacementModes), "Presentation mode <" <<surfaceTraits.swapchainPresentMode << "> not available on GPU and not recognized by library");
VkPresentModeKHR finalPresentationMode = surfaceTraits.swapchainPresentMode;
for (auto it = begin(prefIt->second); it != end(prefIt->second); ++it)
{
auto secondChoiceIt = std::find(begin(presentModes), end(presentModes), *it);
if (secondChoiceIt == end(presentModes))
continue;
finalPresentationMode = *it;
break;
}
CHECK_LOG_THROW(finalPresentationMode == surfaceTraits.swapchainPresentMode, "Presentation mode <" << surfaceTraits.swapchainPresentMode << "> not available on GPU. Library cannot find the replacement");

LOG_WARNING << "Warning : <" << presentationModeNames.at(surfaceTraits.swapchainPresentMode) <<"> presentation mode not available. Library will use <" << presentationModeNames.at(finalPresentationMode) << "> presentation mode instead." << std::endl ;
surfaceTraits.swapchainPresentMode = finalPresentationMode;
}

uint32_t surfaceFormatCount;
VK_CHECK_LOG_THROW( vkGetPhysicalDeviceSurfaceFormatsKHR(phDev, surface, &surfaceFormatCount, nullptr), "Could not get surface formats for surface " << getID());
CHECK_LOG_THROW(surfaceFormatCount == 0, "No surface formats defined for surface " << getID());
Expand Down

0 comments on commit ab7e47b

Please sign in to comment.