From ab7e47beeb8a305913076b1b0697b4a300eb8de0 Mon Sep 17 00:00:00 2001 From: pumexx Date: Tue, 14 Aug 2018 03:25:00 +0200 Subject: [PATCH] When presentation mode chosen by user in SurfaceTraits structure is not 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. --- examples/pumexcrowd/pumexcrowd.cpp | 9 +--- examples/pumexdeferred/pumexdeferred.cpp | 9 +--- examples/pumexgpucull/pumexgpucull.cpp | 9 +--- examples/pumexmultiview/pumexmultiview.cpp | 9 +--- examples/pumexviewer/pumexviewer.cpp | 11 +---- examples/pumexvoxelizer/pumexvoxelizer.cpp | 9 +--- include/pumex/Surface.h | 6 +++ src/pumex/Surface.cpp | 50 ++++++++++++++++++++++ 8 files changed, 63 insertions(+), 49 deletions(-) diff --git a/examples/pumexcrowd/pumexcrowd.cpp b/examples/pumexcrowd/pumexcrowd.cpp index 78885d3..ddde48d 100644 --- a/examples/pumexcrowd/pumexcrowd.cpp +++ b/examples/pumexcrowd/pumexcrowd.cpp @@ -589,18 +589,11 @@ int main(int argc, char * argv[]) { SET_LOG_INFO; - std::unordered_map 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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag 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'}); diff --git a/examples/pumexdeferred/pumexdeferred.cpp b/examples/pumexdeferred/pumexdeferred.cpp index e1023fa..d66f3ee 100644 --- a/examples/pumexdeferred/pumexdeferred.cpp +++ b/examples/pumexdeferred/pumexdeferred.cpp @@ -197,13 +197,6 @@ int main( int argc, char * argv[] ) { SET_LOG_INFO; - std::unordered_map 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 availableSamplesPerPixel { { "1", VK_SAMPLE_COUNT_1_BIT }, @@ -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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60); args::Flag skipDepthPrepass(parser, "nodp", "skip depth prepass", { 'n' }); args::MapFlag samplesPerPixel(parser, "samples", "samples per pixel (1,2,4,8)", { 's' }, availableSamplesPerPixel, VK_SAMPLE_COUNT_4_BIT); diff --git a/examples/pumexgpucull/pumexgpucull.cpp b/examples/pumexgpucull/pumexgpucull.cpp index cbf92fa..d7657bd 100644 --- a/examples/pumexgpucull/pumexgpucull.cpp +++ b/examples/pumexgpucull/pumexgpucull.cpp @@ -1230,18 +1230,11 @@ int main(int argc, char * argv[]) { SET_LOG_INFO; - std::unordered_map 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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag 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' }); diff --git a/examples/pumexmultiview/pumexmultiview.cpp b/examples/pumexmultiview/pumexmultiview.cpp index 5bb814c..8b42764 100644 --- a/examples/pumexmultiview/pumexmultiview.cpp +++ b/examples/pumexmultiview/pumexmultiview.cpp @@ -234,18 +234,11 @@ int main( int argc, char * argv[] ) { SET_LOG_INFO; - std::unordered_map 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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60); try { diff --git a/examples/pumexviewer/pumexviewer.cpp b/examples/pumexviewer/pumexviewer.cpp index 24688a8..668a404 100644 --- a/examples/pumexviewer/pumexviewer.cpp +++ b/examples/pumexviewer/pumexviewer.cpp @@ -140,18 +140,11 @@ int main( int argc, char * argv[] ) SET_LOG_INFO; // process command line using args library - std::unordered_map 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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60); args::Positional modelNameArg(parser, "model", "3D model filename"); args::Positional animationNameArg(parser, "animation", "3D model with animation"); @@ -418,4 +411,4 @@ int main( int argc, char * argv[] ) viewer->cleanup(); FLUSH_LOG; return 0; -} +} diff --git a/examples/pumexvoxelizer/pumexvoxelizer.cpp b/examples/pumexvoxelizer/pumexvoxelizer.cpp index 86d4fcf..a84f565 100644 --- a/examples/pumexvoxelizer/pumexvoxelizer.cpp +++ b/examples/pumexvoxelizer/pumexvoxelizer.cpp @@ -184,18 +184,11 @@ int main( int argc, char * argv[] ) { SET_LOG_INFO; - std::unordered_map 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 presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, availablePresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); + args::MapFlag presentationMode(parser, "presentation_mode", "presentation mode (immediate, mailbox, fifo, fifo_relaxed)", { 'p' }, pumex::Surface::nameToPresentationModes, VK_PRESENT_MODE_MAILBOX_KHR); args::ValueFlag updatesPerSecond(parser, "update_frequency", "number of update calls per second", { 'u' }, 60); args::Positional modelNameArg(parser, "model", "3D model filename" ); args::Positional animationNameArg(parser, "animation", "3D model with animation"); diff --git a/include/pumex/Surface.h b/include/pumex/Surface.h index 4d198b0..23b3c78 100644 --- a/include/pumex/Surface.h +++ b/include/pumex/Surface.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -182,6 +183,11 @@ class PUMEX_EXPORT Surface : public std::enable_shared_from_this void createSwapChain(); bool checkWorkflow(); + +public: + static const std::unordered_map nameToPresentationModes; + static const std::unordered_map presentationModeNames; + static const std::unordered_map> replacementModes; }; bool Surface::isRealized() const { return realized; } diff --git a/src/pumex/Surface.cpp b/src/pumex/Surface.cpp index 17e1376..ab603e3 100644 --- a/src/pumex/Surface.cpp +++ b/src/pumex/Surface.cpp @@ -41,6 +41,31 @@ SurfaceTraits::SurfaceTraits(uint32_t ic, VkColorSpaceKHR ics, uint32_t ial, VkP { } +const std::unordered_map 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 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> 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 v, std::shared_ptr w, std::shared_ptr d, VkSurfaceKHR s, const SurfaceTraits& st) : viewer{ v }, window{ w }, device{ d }, surface{ s }, surfaceTraits(st) { @@ -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 <" < 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());