diff --git a/include/vsg/app/View.h b/include/vsg/app/View.h index c38c5ab14..c7e9f5f6e 100644 --- a/include/vsg/app/View.h +++ b/include/vsg/app/View.h @@ -35,6 +35,8 @@ namespace vsg class VSG_DECLSPEC View : public Inherit { public: + static ModifiedCount modifiedCount(uint32_t viewID); + View(ViewFeatures in_features = RECORD_ALL); // share the specified view's children, viewID, mask and camera ViewportState @@ -63,6 +65,10 @@ namespace vsg /// share the specified view's viewID, mask, camera ViewportState, with this View void share(const View& view); + /// incremented when the pipeline state for the viewID is invalidated + ModifiedCount modifiedCount(); + void modified(); + /// camera controls the viewport state and projection and view matrices ref_ptr camera; diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 997767f1e..0261f29f7 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -95,6 +95,8 @@ namespace vsg virtual ~Implementation(); + ModifiedCount viewModifiedCount; + VkPipeline _pipeline; ref_ptr _device; diff --git a/src/vsg/app/View.cpp b/src/vsg/app/View.cpp index acb5f1de9..eaf114d99 100644 --- a/src/vsg/app/View.cpp +++ b/src/vsg/app/View.cpp @@ -22,6 +22,8 @@ using namespace vsg; // thread safe container for managing the deviceID for each vsg::View static std::mutex s_ViewCountMutex; static std::vector s_ActiveViews; +// these must not be reset to zero when a view ID is reused +static std::vector s_ViewIDModifiedCounts; static uint32_t getUniqueViewID() { @@ -38,6 +40,7 @@ static uint32_t getUniqueViewID() } s_ActiveViews.push_back(1); + s_ViewIDModifiedCounts.emplace_back(); return viewID; } @@ -62,6 +65,12 @@ static void releaseViewID(uint32_t viewID) { std::scoped_lock guard(s_ViewCountMutex); --s_ActiveViews[viewID]; + ++s_ViewIDModifiedCounts[viewID]; +} + +ModifiedCount vsg::View::modifiedCount(uint32_t viewID) +{ + return s_ViewIDModifiedCounts[viewID]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -125,3 +134,13 @@ void View::share(const View& view) camera->viewportState = view.camera->viewportState; } } + +ModifiedCount vsg::View::modifiedCount() +{ + return s_ViewIDModifiedCounts[viewID]; +} + +void vsg::View::modified() +{ + ++s_ViewIDModifiedCounts[viewID]; +} diff --git a/src/vsg/app/WindowResizeHandler.cpp b/src/vsg/app/WindowResizeHandler.cpp index b28f94371..69a1b2dd6 100644 --- a/src/vsg/app/WindowResizeHandler.cpp +++ b/src/vsg/app/WindowResizeHandler.cpp @@ -45,7 +45,6 @@ void UpdateGraphicsPipelines::apply(vsg::BindGraphicsPipeline& bindPipeline) auto pipeline = bindPipeline.pipeline; if (pipeline) { - pipeline->release(context->viewID); pipeline->compile(*context); } } @@ -118,7 +117,6 @@ void WindowResizeHandler::apply(vsg::BindGraphicsPipeline& bindPipeline) bool needToRegenerateGraphicsPipeline = !containsViewport(*graphicsPipeline); if (needToRegenerateGraphicsPipeline) { - graphicsPipeline->release(context->viewID); graphicsPipeline->compile(*context); } } @@ -144,11 +142,13 @@ void WindowResizeHandler::apply(vsg::View& view) { if (!visit(&view)) return; + auto previous_viewID = context->viewID; context->viewID = view.viewID; if (!view.camera) { view.traverse(*this); + context->viewID = previous_viewID; return; } @@ -178,9 +178,12 @@ void WindowResizeHandler::apply(vsg::View& view) } } + view.modified(); + context->defaultPipelineStates.emplace_back(viewportState); view.traverse(*this); context->defaultPipelineStates.pop_back(); + context->viewID = previous_viewID; } diff --git a/src/vsg/state/GraphicsPipeline.cpp b/src/vsg/state/GraphicsPipeline.cpp index 5e7e4870a..870c325ea 100644 --- a/src/vsg/state/GraphicsPipeline.cpp +++ b/src/vsg/state/GraphicsPipeline.cpp @@ -10,6 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ +#include #include #include #include @@ -138,7 +139,7 @@ void GraphicsPipeline::compile(Context& context) _implementation.resize(viewID + 1); } - if (!_implementation[viewID]) + if (!_implementation[viewID] || _implementation[viewID]->viewModifiedCount != View::modifiedCount(context.viewID)) { // compile shaders if required bool requiresShaderCompiler = false; @@ -189,6 +190,7 @@ void GraphicsPipeline::compile(Context& context) // GraphicsPipeline::Implementation // GraphicsPipeline::Implementation::Implementation(Context& context, Device* device, const RenderPass* renderPass, const PipelineLayout* pipelineLayout, const ShaderStages& shaderStages, const GraphicsPipelineStates& pipelineStates, uint32_t subpass) : + viewModifiedCount(View::modifiedCount(context.viewID)), _device(device) { VkGraphicsPipelineCreateInfo pipelineInfo = {};