From 88295fb686a4f76f203becfb6b6a9fc022186b12 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 23 Aug 2024 18:12:54 +0100 Subject: [PATCH 01/26] Use dynamic viewport and scissor by default Backwards compatibility is maximised by making this be set by default on DynamicState instances (so applications that already use dynamic state don't need to explicitly set extra state) and having Context have a defaulted DynamicState instance unless otherwise specified. No changes were required to vsgExamples as far as I can tell, although there's some code in vsgmultiviews.cpp that becomes unnecessary when swapping views. This could be implemented a little differently if SetScissor and SetViewport were changed to be StateCommands instead of plain Commands, as then they could just be pushed to state stacks during the record traversal instead of being controlled by ViewDependentState and needing explicitly dirtying if ever used without a Camera. I didn't do this in this initial implementation because it would invite discussion about which other dynamic state related Command subclasses should be turned into StateCommands at the same time and whether the slot system as it already exists is friendly towards that given that descriptor sets can eat arbitrarily many slots from 2+. I've stripped the pipeline recreation from WindowResizeHandler as it already wasn't entirely reliable and if someone's mad enough to opt back into baked-in viewports despite using a resizable window, they can create a subclass. --- include/vsg/app/WindowResizeHandler.h | 3 +- include/vsg/state/DynamicState.h | 1 + include/vsg/state/ViewDependentState.h | 7 +++++ src/vsg/app/RecordTraversal.cpp | 28 +++++++++++------- src/vsg/app/RenderGraph.cpp | 14 --------- src/vsg/app/WindowResizeHandler.cpp | 40 -------------------------- src/vsg/commands/SetScissor.cpp | 3 ++ src/vsg/commands/SetViewport.cpp | 3 ++ src/vsg/state/DynamicState.cpp | 3 +- src/vsg/state/ViewDependentState.cpp | 13 +++++++++ src/vsg/vk/Context.cpp | 3 ++ 11 files changed, 51 insertions(+), 67 deletions(-) diff --git a/include/vsg/app/WindowResizeHandler.h b/include/vsg/app/WindowResizeHandler.h index fe99165c21..236245dcc7 100644 --- a/include/vsg/app/WindowResizeHandler.h +++ b/include/vsg/app/WindowResizeHandler.h @@ -23,6 +23,7 @@ namespace vsg /// Utility class for updating a scene graph when a View's camera ViewportState has been updated so that associated GraphicsPipelines in the /// scene graph can be recompiled and correctly reflect the new ViewportState. + /// As viewport size and scissor is dynamic by default, this is only necessary when opting out of that or when the viewport count has changed. class VSG_DECLSPEC UpdateGraphicsPipelines : public Inherit { public: @@ -43,7 +44,6 @@ namespace vsg class VSG_DECLSPEC WindowResizeHandler : public Inherit { public: - ref_ptr context; VkRect2D renderArea; VkExtent2D previous_extent; VkExtent2D new_extent; @@ -63,7 +63,6 @@ namespace vsg /// return true if the object was visited bool visit(const Object* object, uint32_t index = 0); - void apply(BindGraphicsPipeline& bindPipeline) override; void apply(Object& object) override; void apply(ClearAttachments& clearAttachments) override; void apply(View& view) override; diff --git a/include/vsg/state/DynamicState.h b/include/vsg/state/DynamicState.h index 06397f2250..420025129b 100644 --- a/include/vsg/state/DynamicState.h +++ b/include/vsg/state/DynamicState.h @@ -18,6 +18,7 @@ namespace vsg { /// DynamicState encapsulates VkPipelineDynamicStateCreateInfo settings passed when setting up GraphicsPipeline + /// By default, viewport and scissor are set to dynamic class VSG_DECLSPEC DynamicState : public Inherit { public: diff --git a/include/vsg/state/ViewDependentState.h b/include/vsg/state/ViewDependentState.h index 56adc361df..aa363eebe2 100644 --- a/include/vsg/state/ViewDependentState.h +++ b/include/vsg/state/ViewDependentState.h @@ -14,6 +14,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include #include #include #include @@ -21,6 +22,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include namespace vsg { @@ -140,6 +142,11 @@ namespace vsg ref_ptr lightData; ref_ptr lightDataBufferInfo; + Viewports viewports; + Scissors scissors; + bool viewportsDirty; + bool scissorsDirty; + ref_ptr viewportData; ref_ptr viewportDataBufferInfo; diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 3b173c0879..b3d280cc04 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -541,22 +541,30 @@ void RecordTraversal::apply(const View& view) _state->inheritViewForLODScaling = (view.features & INHERIT_VIEWPOINT) != 0; _state->setProjectionAndViewMatrix(view.camera->projectionMatrix->transform(), view.camera->viewMatrix->transform()); - if (_viewDependentState && _viewDependentState->viewportData && view.camera->viewportState) + if (_viewDependentState && view.camera->viewportState) { auto& viewportData = _viewDependentState->viewportData; auto& viewports = view.camera->viewportState->viewports; - auto dest_itr = viewportData->begin(); - for (auto src_itr = viewports.begin(); - dest_itr != viewportData->end() && src_itr != viewports.end(); - ++dest_itr, ++src_itr) + _viewDependentState->viewports = viewports; + _viewDependentState->viewportsDirty = true; + _viewDependentState->scissors = view.camera->viewportState->scissors; + _viewDependentState->scissorsDirty = true; + + if (viewportData) { - auto& dest_viewport = *dest_itr; - vec4 src_viewport(src_itr->x, src_itr->y, src_itr->width, src_itr->height); - if (dest_viewport != src_viewport) + auto dest_itr = viewportData->begin(); + for (auto src_itr = viewports.begin(); + dest_itr != viewportData->end() && src_itr != viewports.end(); + ++dest_itr, ++src_itr) { - dest_viewport = src_viewport; - viewportData->dirty(); + auto& dest_viewport = *dest_itr; + vec4 src_viewport(src_itr->x, src_itr->y, src_itr->width, src_itr->height); + if (dest_viewport != src_viewport) + { + dest_viewport = src_viewport; + viewportData->dirty(); + } } } } diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index 20cb187a29..852ac1a080 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -159,27 +159,13 @@ void RenderGraph::resized() auto activeRenderPass = getRenderPass(); if (!activeRenderPass) return; - auto device = activeRenderPass->device; - - if (!windowResizeHandler->context) windowResizeHandler->context = vsg::Context::create(device); - auto extent = getExtent(); - windowResizeHandler->context->commandPool = nullptr; - windowResizeHandler->context->renderPass = activeRenderPass; windowResizeHandler->renderArea = renderArea; windowResizeHandler->previous_extent = previous_extent; windowResizeHandler->new_extent = extent; windowResizeHandler->visited.clear(); - if (activeRenderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) - { - windowResizeHandler->context->overridePipelineStates.emplace_back(vsg::MultisampleState::create(activeRenderPass->maxSamples)); - } - - // make sure the device is idle before we recreate any Vulkan objects - vkDeviceWaitIdle(*(device)); - traverse(*windowResizeHandler); windowResizeHandler->scale_rect(renderArea); diff --git a/src/vsg/app/WindowResizeHandler.cpp b/src/vsg/app/WindowResizeHandler.cpp index b28f94371f..3fe8d63218 100644 --- a/src/vsg/app/WindowResizeHandler.cpp +++ b/src/vsg/app/WindowResizeHandler.cpp @@ -90,40 +90,6 @@ bool WindowResizeHandler::visit(const Object* object, uint32_t index) return true; } -void WindowResizeHandler::apply(vsg::BindGraphicsPipeline& bindPipeline) -{ - GraphicsPipeline* graphicsPipeline = bindPipeline.pipeline; - - if (!visit(graphicsPipeline, context->viewID)) - { - return; - } - - if (graphicsPipeline) - { - struct ContainsViewport : public ConstVisitor - { - bool foundViewport = false; - void apply(const ViewportState&) override { foundViewport = true; } - bool operator()(const GraphicsPipeline& gp) - { - for (auto& pipelineState : gp.pipelineStates) - { - pipelineState->accept(*this); - } - return foundViewport; - } - } containsViewport; - - bool needToRegenerateGraphicsPipeline = !containsViewport(*graphicsPipeline); - if (needToRegenerateGraphicsPipeline) - { - graphicsPipeline->release(context->viewID); - graphicsPipeline->compile(*context); - } - } -} - void WindowResizeHandler::apply(vsg::Object& object) { object.traverse(*this); @@ -144,8 +110,6 @@ void WindowResizeHandler::apply(vsg::View& view) { if (!visit(&view)) return; - context->viewID = view.viewID; - if (!view.camera) { view.traverse(*this); @@ -178,9 +142,5 @@ void WindowResizeHandler::apply(vsg::View& view) } } - context->defaultPipelineStates.emplace_back(viewportState); - view.traverse(*this); - - context->defaultPipelineStates.pop_back(); } diff --git a/src/vsg/commands/SetScissor.cpp b/src/vsg/commands/SetScissor.cpp index 7d91a80b95..86511b4664 100644 --- a/src/vsg/commands/SetScissor.cpp +++ b/src/vsg/commands/SetScissor.cpp @@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include #include using namespace vsg; @@ -30,4 +31,6 @@ SetScissor::SetScissor(uint32_t in_firstScissor, const Scissors& in_scissors) : void SetScissor::record(CommandBuffer& commandBuffer) const { vkCmdSetScissor(commandBuffer, firstScissor, static_cast(scissors.size()), scissors.data()); + if (commandBuffer.viewDependentState) + commandBuffer.viewDependentState->scissorsDirty = true; } diff --git a/src/vsg/commands/SetViewport.cpp b/src/vsg/commands/SetViewport.cpp index be717bfee5..9c8a6fb878 100644 --- a/src/vsg/commands/SetViewport.cpp +++ b/src/vsg/commands/SetViewport.cpp @@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include #include using namespace vsg; @@ -30,4 +31,6 @@ SetViewport::SetViewport(uint32_t in_firstViewport, const Viewports& in_viewport void SetViewport::record(CommandBuffer& commandBuffer) const { vkCmdSetViewport(commandBuffer, firstViewport, static_cast(viewports.size()), viewports.data()); + if (commandBuffer.viewDependentState) + commandBuffer.viewDependentState->viewportsDirty = true; } diff --git a/src/vsg/state/DynamicState.cpp b/src/vsg/state/DynamicState.cpp index 690371bed9..5efe6cf802 100644 --- a/src/vsg/state/DynamicState.cpp +++ b/src/vsg/state/DynamicState.cpp @@ -17,7 +17,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -DynamicState::DynamicState() +DynamicState::DynamicState() : + dynamicStates({VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}) { } diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 929605a039..0d48ee3369 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -293,6 +293,9 @@ void ViewDependentState::init(ResourceRequirements& requirements) lightDataBufferInfo = BufferInfo::create(lightData.get()); descriptorConfigurator->assignDescriptor("lightData", BufferInfoList{lightDataBufferInfo}); + viewportsDirty = true; + scissorsDirty = true; + viewportData = vec4Array::create(maxViewports); viewportData->properties.dataVariance = DYNAMIC_DATA_TRANSFER_AFTER_RECORD; viewportDataBufferInfo = BufferInfo::create(viewportData.get()); @@ -1033,4 +1036,14 @@ void ViewDependentState::bindDescriptorSets(CommandBuffer& commandBuffer, VkPipe { auto vk = descriptorSet->vk(commandBuffer.deviceID); vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, 1, &vk, 0, nullptr); + if (viewportsDirty) + { + vkCmdSetViewport(commandBuffer, 0, static_cast(viewports.size()), viewports.data()); + viewportsDirty = false; + } + if (scissorsDirty) + { + vkCmdSetScissor(commandBuffer, 0, static_cast(scissors.size()), scissors.data()); + scissorsDirty = false; + } } diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index 4c98fd04d4..df72f035c5 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -23,6 +23,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include @@ -129,6 +130,8 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi { vsg::debug("Context::Context() reusing descriptorPools = ", descriptorPools); } + + defaultPipelineStates.push_back(DynamicState::create()); } Context::Context(const Context& context) : From 71d1f0ca9cca4764331f7f410385df7779c05f66 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 18 Sep 2024 18:35:26 +0100 Subject: [PATCH 02/26] Track viewport with State ViewDependentState was less appropriate, and didn't necessarily exist for all the things that might have provided the non-dynamic viewport. I think I've covered everything this time. --- include/vsg/state/ViewDependentState.h | 5 ----- include/vsg/vk/State.h | 6 ++++++ src/vsg/app/CommandGraph.cpp | 15 +++++++++++++++ src/vsg/app/RecordTraversal.cpp | 14 ++++++++++---- src/vsg/app/RenderGraph.cpp | 14 ++++++++++++++ src/vsg/app/SecondaryCommandGraph.cpp | 15 +++++++++++++++ src/vsg/commands/SetScissor.cpp | 3 --- src/vsg/commands/SetViewport.cpp | 3 --- src/vsg/state/ViewDependentState.cpp | 13 ------------- 9 files changed, 60 insertions(+), 28 deletions(-) diff --git a/include/vsg/state/ViewDependentState.h b/include/vsg/state/ViewDependentState.h index aa363eebe2..46492f487c 100644 --- a/include/vsg/state/ViewDependentState.h +++ b/include/vsg/state/ViewDependentState.h @@ -142,11 +142,6 @@ namespace vsg ref_ptr lightData; ref_ptr lightDataBufferInfo; - Viewports viewports; - Scissors scissors; - bool viewportsDirty; - bool scissorsDirty; - ref_ptr viewportData; ref_ptr viewportDataBufferInfo; diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index a5280daab9..e2489d0d2d 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -255,6 +255,9 @@ namespace vsg MatrixStack projectionMatrixStack{0}; MatrixStack modelviewMatrixStack{64}; + StateStack scissorStack{}; + StateStack viewportStack{}; + void setInhertiedViewProjectionAndViewMatrix(const dmat4& projMatrix, const dmat4& viewMatrix) { inheritedProjectionMatrix = projMatrix; @@ -292,6 +295,9 @@ namespace vsg stateStack.record(*_commandBuffer); } + scissorStack.record(*_commandBuffer); + viewportStack.record(*_commandBuffer); + projectionMatrixStack.record(*_commandBuffer); modelviewMatrixStack.record(*_commandBuffer); diff --git a/src/vsg/app/CommandGraph.cpp b/src/vsg/app/CommandGraph.cpp index 4e06fc91a6..a25faf5ca1 100644 --- a/src/vsg/app/CommandGraph.cpp +++ b/src/vsg/app/CommandGraph.cpp @@ -13,6 +13,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include +#include #include #include #include @@ -119,6 +121,13 @@ void CommandGraph::record(ref_ptr recordedCommandBuffers recordTraversal->getState()->_commandBuffer = commandBuffer; + if (framebuffer || window) + { + const VkExtent2D& extent = framebuffer ? framebuffer->extent2D() : window->extent2D(); + recordTraversal->getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); + recordTraversal->getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); + } + // or select index when maps to a dormant CommandBuffer VkCommandBuffer vk_commandBuffer = *commandBuffer; @@ -138,6 +147,12 @@ void CommandGraph::record(ref_ptr recordedCommandBuffers vkEndCommandBuffer(vk_commandBuffer); + if (framebuffer || window) + { + recordTraversal->getState()->scissorStack.pop(); + recordTraversal->getState()->viewportStack.pop(); + } + recordedCommandBuffers->add(submitOrder, commandBuffer); } diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index b3d280cc04..ca587b23cc 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -16,6 +16,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include +#include #include #include #include @@ -546,10 +548,8 @@ void RecordTraversal::apply(const View& view) auto& viewportData = _viewDependentState->viewportData; auto& viewports = view.camera->viewportState->viewports; - _viewDependentState->viewports = viewports; - _viewDependentState->viewportsDirty = true; - _viewDependentState->scissors = view.camera->viewportState->scissors; - _viewDependentState->scissorsDirty = true; + _state->scissorStack.push(vsg::SetScissor::create(0, view.camera->viewportState->scissors)); + _state->viewportStack.push(vsg::SetViewport::create(0, viewports)); if (viewportData) { @@ -570,6 +570,12 @@ void RecordTraversal::apply(const View& view) } view.traverse(*this); + + if (_viewDependentState && view.camera->viewportState) + { + _state->scissorStack.pop(); + _state->viewportStack.pop(); + } } else { diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index 852ac1a080..c69f504f4e 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -12,6 +12,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include +#include #include #include #include @@ -142,6 +144,12 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); + if (extent.width != invalid_dimension && extent.height != invalid_dimension) + { + recordTraversal.getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); + recordTraversal.getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); + } + VkCommandBuffer vk_commandBuffer = *(recordTraversal.getState()->_commandBuffer); vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents); @@ -149,6 +157,12 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const traverse(recordTraversal); vkCmdEndRenderPass(vk_commandBuffer); + + if (extent.width != invalid_dimension && extent.height != invalid_dimension) + { + recordTraversal.getState()->scissorStack.pop(); + recordTraversal.getState()->viewportStack.pop(); + } } void RenderGraph::resized() diff --git a/src/vsg/app/SecondaryCommandGraph.cpp b/src/vsg/app/SecondaryCommandGraph.cpp index 7166c046ba..6bb9443e48 100644 --- a/src/vsg/app/SecondaryCommandGraph.cpp +++ b/src/vsg/app/SecondaryCommandGraph.cpp @@ -14,6 +14,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include +#include #include #include #include @@ -155,12 +157,25 @@ void SecondaryCommandGraph::record(ref_ptr recordedComma inheritanceInfo.framebuffer = VK_NULL_HANDLE; } + if (framebuffer || window) + { + const VkExtent2D& extent = framebuffer ? framebuffer->extent2D() : window->extent2D(); + recordTraversal->getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); + recordTraversal->getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); + } + vkBeginCommandBuffer(vk_commandBuffer, &beginInfo); traverse(*recordTraversal); vkEndCommandBuffer(vk_commandBuffer); + if (framebuffer || window) + { + recordTraversal->getState()->scissorStack.pop(); + recordTraversal->getState()->viewportStack.pop(); + } + // pass on this command buffer to connected ExecuteCommands nodes for (auto& ec : _executeCommands) { diff --git a/src/vsg/commands/SetScissor.cpp b/src/vsg/commands/SetScissor.cpp index 86511b4664..7d91a80b95 100644 --- a/src/vsg/commands/SetScissor.cpp +++ b/src/vsg/commands/SetScissor.cpp @@ -12,7 +12,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include #include using namespace vsg; @@ -31,6 +30,4 @@ SetScissor::SetScissor(uint32_t in_firstScissor, const Scissors& in_scissors) : void SetScissor::record(CommandBuffer& commandBuffer) const { vkCmdSetScissor(commandBuffer, firstScissor, static_cast(scissors.size()), scissors.data()); - if (commandBuffer.viewDependentState) - commandBuffer.viewDependentState->scissorsDirty = true; } diff --git a/src/vsg/commands/SetViewport.cpp b/src/vsg/commands/SetViewport.cpp index 9c8a6fb878..be717bfee5 100644 --- a/src/vsg/commands/SetViewport.cpp +++ b/src/vsg/commands/SetViewport.cpp @@ -12,7 +12,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include #include using namespace vsg; @@ -31,6 +30,4 @@ SetViewport::SetViewport(uint32_t in_firstViewport, const Viewports& in_viewport void SetViewport::record(CommandBuffer& commandBuffer) const { vkCmdSetViewport(commandBuffer, firstViewport, static_cast(viewports.size()), viewports.data()); - if (commandBuffer.viewDependentState) - commandBuffer.viewDependentState->viewportsDirty = true; } diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 0d48ee3369..929605a039 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -293,9 +293,6 @@ void ViewDependentState::init(ResourceRequirements& requirements) lightDataBufferInfo = BufferInfo::create(lightData.get()); descriptorConfigurator->assignDescriptor("lightData", BufferInfoList{lightDataBufferInfo}); - viewportsDirty = true; - scissorsDirty = true; - viewportData = vec4Array::create(maxViewports); viewportData->properties.dataVariance = DYNAMIC_DATA_TRANSFER_AFTER_RECORD; viewportDataBufferInfo = BufferInfo::create(viewportData.get()); @@ -1036,14 +1033,4 @@ void ViewDependentState::bindDescriptorSets(CommandBuffer& commandBuffer, VkPipe { auto vk = descriptorSet->vk(commandBuffer.deviceID); vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, 1, &vk, 0, nullptr); - if (viewportsDirty) - { - vkCmdSetViewport(commandBuffer, 0, static_cast(viewports.size()), viewports.data()); - viewportsDirty = false; - } - if (scissorsDirty) - { - vkCmdSetScissor(commandBuffer, 0, static_cast(scissors.size()), scissors.data()); - scissorsDirty = false; - } } From 072a38a8ecd82a3ebf4bf76426c5ab89d0a55e47 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 18 Sep 2024 18:37:09 +0100 Subject: [PATCH 03/26] Prune headers --- include/vsg/state/ViewDependentState.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/vsg/state/ViewDependentState.h b/include/vsg/state/ViewDependentState.h index 46492f487c..56adc361df 100644 --- a/include/vsg/state/ViewDependentState.h +++ b/include/vsg/state/ViewDependentState.h @@ -14,7 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include #include #include #include @@ -22,7 +21,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include namespace vsg { From 4cc5c36ef79b8a1d101032e95f274fd3f279e3eb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 8 Feb 2025 13:41:15 +0000 Subject: [PATCH 04/26] Experimental ViewportState with built in support for vkCmdSetViewport and vkCmdSetScissor. --- include/vsg/state/GraphicsPipeline.h | 3 ++- include/vsg/state/ViewportState.h | 3 +++ include/vsg/vk/State.h | 3 --- src/vsg/app/RecordTraversal.cpp | 25 +++++++++++++++---------- src/vsg/state/ViewportState.cpp | 13 +++++++++++-- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 6e3e20da88..0776890f51 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -25,7 +25,7 @@ namespace vsg /// Base class for setting up the various pipeline states with the VkGraphicsPipelineCreateInfo /// Subclasses are ColorBlendState, DepthStencilState, DynamicState, InputAssemblyState, /// MultisampleState, RasterizationState, TessellationState, VertexInputState and ViewportState. - class VSG_DECLSPEC GraphicsPipelineState : public Inherit + class VSG_DECLSPEC GraphicsPipelineState : public Inherit { public: GraphicsPipelineState() {} @@ -36,6 +36,7 @@ namespace vsg Mask mask = MASK_ALL; virtual void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const = 0; + void record(CommandBuffer&) const override {}; public: int compare(const Object& rhs) const override; diff --git a/include/vsg/state/ViewportState.h b/include/vsg/state/ViewportState.h index 1d6a8991a1..89ac086340 100644 --- a/include/vsg/state/ViewportState.h +++ b/include/vsg/state/ViewportState.h @@ -51,6 +51,9 @@ namespace vsg void write(Output& output) const override; void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; + /// enable ViewportState to be recorded via vkCmdSetScissor and vkCmdSetViewport + void record(CommandBuffer& commandBuffer) const override; + protected: virtual ~ViewportState(); }; diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index e52da8e3a0..6bf05e24db 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -295,9 +295,6 @@ namespace vsg stateStack.record(*_commandBuffer); } - scissorStack.record(*_commandBuffer); - viewportStack.record(*_commandBuffer); - projectionMatrixStack.record(*_commandBuffer); modelviewMatrixStack.record(*_commandBuffer); diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 8b75fd91db..ba3a1a06ab 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -577,13 +577,21 @@ void RecordTraversal::apply(const View& view) _state->inheritViewForLODScaling = (view.features & INHERIT_VIEWPOINT) != 0; _state->setProjectionAndViewMatrix(view.camera->projectionMatrix->transform(), view.camera->viewMatrix->transform()); - if (_viewDependentState && view.camera->viewportState) + auto& viewportState = view.camera->viewportState; + + if (viewportState->slot >= _state->stateStacks.size()) { - auto& viewportData = _viewDependentState->viewportData; - auto& viewports = view.camera->viewportState->viewports; + _state->stateStacks.resize(viewportState->slot+1); + // info("RecordTraversal::apply(const View& view) _state->stateStacks.size() not big enough, expanding to viewportState->slot+1."); + } + + _state->stateStacks[viewportState->slot].push(viewportState); + _state->dirty = true; - _state->scissorStack.push(vsg::SetScissor::create(0, view.camera->viewportState->scissors)); - _state->viewportStack.push(vsg::SetViewport::create(0, viewports)); + if (_viewDependentState && viewportState) + { + auto& viewports = viewportState->viewports; + auto& viewportData = _viewDependentState->viewportData; if (viewportData) { @@ -605,11 +613,8 @@ void RecordTraversal::apply(const View& view) view.traverse(*this); - if (_viewDependentState && view.camera->viewportState) - { - _state->scissorStack.pop(); - _state->viewportStack.pop(); - } + _state->stateStacks[viewportState->slot].pop(); + _state->dirty = true; } else { diff --git a/src/vsg/state/ViewportState.cpp b/src/vsg/state/ViewportState.cpp index ebaad250d4..087453c096 100644 --- a/src/vsg/state/ViewportState.cpp +++ b/src/vsg/state/ViewportState.cpp @@ -18,6 +18,7 @@ using namespace vsg; ViewportState::ViewportState() { + slot = 3; } ViewportState::ViewportState(const ViewportState& vs) : @@ -27,12 +28,14 @@ ViewportState::ViewportState(const ViewportState& vs) : { } -ViewportState::ViewportState(const VkExtent2D& extent) +ViewportState::ViewportState(const VkExtent2D& extent): + ViewportState() { set(0, 0, extent.width, extent.height); } -ViewportState::ViewportState(int32_t x, int32_t y, uint32_t width, uint32_t height) +ViewportState::ViewportState(int32_t x, int32_t y, uint32_t width, uint32_t height): + ViewportState() { set(x, y, width, height); } @@ -136,6 +139,12 @@ void ViewportState::apply(Context& context, VkGraphicsPipelineCreateInfo& pipeli pipelineInfo.pViewportState = viewportState; } +void ViewportState::record(CommandBuffer& commandBuffer) const +{ + vkCmdSetScissor(commandBuffer, 0, static_cast(scissors.size()), scissors.data()); + vkCmdSetViewport(commandBuffer, 0, static_cast(viewports.size()), viewports.data()); +} + VkViewport& ViewportState::getViewport() { if (viewports.empty()) From 644ed2819eded2a1971beda14625f27df5a5a07b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 8 Feb 2025 17:00:02 +0000 Subject: [PATCH 05/26] Removed no longer required code. --- include/vsg/vk/State.h | 3 --- src/vsg/app/CommandGraph.cpp | 15 --------------- src/vsg/app/RecordTraversal.cpp | 2 -- src/vsg/app/RenderGraph.cpp | 14 -------------- src/vsg/app/SecondaryCommandGraph.cpp | 15 --------------- 5 files changed, 49 deletions(-) diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index 6bf05e24db..49b7549a6f 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -255,9 +255,6 @@ namespace vsg MatrixStack projectionMatrixStack{0}; MatrixStack modelviewMatrixStack{64}; - StateStack scissorStack{}; - StateStack viewportStack{}; - void setInhertiedViewProjectionAndViewMatrix(const dmat4& projMatrix, const dmat4& viewMatrix) { inheritedProjectionMatrix = projMatrix; diff --git a/src/vsg/app/CommandGraph.cpp b/src/vsg/app/CommandGraph.cpp index a7ea02f3ff..e8ac3d4991 100644 --- a/src/vsg/app/CommandGraph.cpp +++ b/src/vsg/app/CommandGraph.cpp @@ -13,8 +13,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include -#include #include #include #include @@ -122,13 +120,6 @@ void CommandGraph::record(ref_ptr recordedCommandBuffers recordTraversal->getState()->_commandBuffer = commandBuffer; - if (framebuffer || window) - { - const VkExtent2D& extent = framebuffer ? framebuffer->extent2D() : window->extent2D(); - recordTraversal->getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); - recordTraversal->getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); - } - // or select index when maps to a dormant CommandBuffer VkCommandBuffer vk_commandBuffer = *commandBuffer; @@ -148,12 +139,6 @@ void CommandGraph::record(ref_ptr recordedCommandBuffers vkEndCommandBuffer(vk_commandBuffer); - if (framebuffer || window) - { - recordTraversal->getState()->scissorStack.pop(); - recordTraversal->getState()->viewportStack.pop(); - } - recordedCommandBuffers->add(submitOrder, commandBuffer); } diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index ba3a1a06ab..b84d28760c 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -16,8 +16,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include -#include #include #include #include diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index c962e67213..fb48386f5a 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -12,8 +12,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include -#include #include #include #include @@ -143,12 +141,6 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); - if (extent.width != invalid_dimension && extent.height != invalid_dimension) - { - recordTraversal.getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); - recordTraversal.getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); - } - VkCommandBuffer vk_commandBuffer = *(recordTraversal.getState()->_commandBuffer); vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents); @@ -156,12 +148,6 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const traverse(recordTraversal); vkCmdEndRenderPass(vk_commandBuffer); - - if (extent.width != invalid_dimension && extent.height != invalid_dimension) - { - recordTraversal.getState()->scissorStack.pop(); - recordTraversal.getState()->viewportStack.pop(); - } } void RenderGraph::resized() diff --git a/src/vsg/app/SecondaryCommandGraph.cpp b/src/vsg/app/SecondaryCommandGraph.cpp index 620b04b828..3d24d72b6f 100644 --- a/src/vsg/app/SecondaryCommandGraph.cpp +++ b/src/vsg/app/SecondaryCommandGraph.cpp @@ -14,8 +14,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include -#include #include #include #include @@ -157,25 +155,12 @@ void SecondaryCommandGraph::record(ref_ptr recordedComma inheritanceInfo.framebuffer = VK_NULL_HANDLE; } - if (framebuffer || window) - { - const VkExtent2D& extent = framebuffer ? framebuffer->extent2D() : window->extent2D(); - recordTraversal->getState()->scissorStack.push(SetScissor::create(0, Scissors{{{0, 0}, extent}})); - recordTraversal->getState()->viewportStack.push(SetViewport::create(0, Viewports{{0.0f, 0.0f, static_cast(extent.width), static_cast(extent.height), 0.0f, 1.0f}})); - } - vkBeginCommandBuffer(vk_commandBuffer, &beginInfo); traverse(*recordTraversal); vkEndCommandBuffer(vk_commandBuffer); - if (framebuffer || window) - { - recordTraversal->getState()->scissorStack.pop(); - recordTraversal->getState()->viewportStack.pop(); - } - // pass on this command buffer to connected ExecuteCommands nodes for (auto& ec : _executeCommands) { From 266560e4795a4264b7683c21176dca3ff0a7979e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 8 Feb 2025 17:58:57 +0000 Subject: [PATCH 06/26] Removed passing ViewportState to compile traversal. --- src/vsg/app/CompileTraversal.cpp | 34 -------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 9cab1e388f..39a25f49c2 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -89,11 +89,6 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, r context->graphicsQueue = device->getQueue(queueFamily, queueFamilyIndex); context->transferTask = transferTask; - if (viewport) - context->defaultPipelineStates.emplace_back(viewport); - else - context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(window.extent2D())); - if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) context->overridePipelineStates.emplace_back(MultisampleState::create(renderPass->maxSamples)); contexts.push_back(context); @@ -120,11 +115,6 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, r context->overridePipelineStates.insert(context->overridePipelineStates.end(), view->overridePipelineStates.begin(), view->overridePipelineStates.end()); - if (view->camera && view->camera->viewportState) - context->defaultPipelineStates.emplace_back(view->camera->viewportState); - else - context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(window.extent2D())); - context->view = view.get(); context->viewID = view->viewID; context->viewDependentState = view->viewDependentState; @@ -159,11 +149,6 @@ void CompileTraversal::add(ref_ptr context, Framebuffer& framebuffer, r if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) context->overridePipelineStates.emplace_back(vsg::MultisampleState::create(renderPass->maxSamples)); context->overridePipelineStates.insert(context->overridePipelineStates.end(), view->overridePipelineStates.begin(), view->overridePipelineStates.end()); - if (view->camera && view->camera->viewportState) - context->defaultPipelineStates.emplace_back(view->camera->viewportState); - else - context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(framebuffer.extent2D())); - context->view = view.get(); context->viewID = view->viewID; context->viewDependentState = view->viewDependentState; @@ -352,15 +337,6 @@ void CompileTraversal::apply(SecondaryCommandGraph& secondaryCommandGraph) context->renderPass = renderPass; - if (secondaryCommandGraph.window) - { - mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(secondaryCommandGraph.window->extent2D())); - } - else if (secondaryCommandGraph.framebuffer) - { - mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(secondaryCommandGraph.framebuffer->extent2D())); - } - if (renderPass) { mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); @@ -387,15 +363,6 @@ void CompileTraversal::apply(RenderGraph& renderGraph) auto previousOverridePipelineStates = context->overridePipelineStates; context->renderPass = renderGraph.getRenderPass(); - if (renderGraph.window) - { - mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(renderGraph.window->extent2D())); - } - else if (renderGraph.framebuffer) - { - mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(renderGraph.framebuffer->extent2D())); - } - if (context->renderPass) { mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); @@ -438,7 +405,6 @@ void CompileTraversal::apply(View& view) } // assign view specific pipeline states - if (view.camera && view.camera->viewportState) mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, view.camera->viewportState); mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, view.overridePipelineStates); view.traverse(*this); From 9d17041fe0a871da90c7023a99b5aa3aacc18b5b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 8 Feb 2025 18:23:52 +0000 Subject: [PATCH 07/26] Simplified CompileManager and CompileTraversal removing ViewportState centric methods that are no longer required. --- include/vsg/app/CompileManager.h | 2 +- include/vsg/app/CompileTraversal.h | 9 ++++----- src/vsg/app/CompileManager.cpp | 4 ++-- src/vsg/app/CompileTraversal.cpp | 12 +++--------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index 5f28abd71a..7b403433ab 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -49,7 +49,7 @@ namespace vsg void add(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for Window and associated viewport. - void add(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); + void add(Window& window, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for View void add(Window& window, ref_ptr view, const ResourceRequirements& resourceRequirements = {}); diff --git a/include/vsg/app/CompileTraversal.h b/include/vsg/app/CompileTraversal.h index fa9fdf1809..235b0cb5e9 100644 --- a/include/vsg/app/CompileTraversal.h +++ b/include/vsg/app/CompileTraversal.h @@ -36,7 +36,6 @@ namespace vsg CompileTraversal() { overrideMask = vsg::MASK_ALL; } CompileTraversal(const CompileTraversal& ct); explicit CompileTraversal(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); - explicit CompileTraversal(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); explicit CompileTraversal(const Viewer& viewer, const ResourceRequirements& resourceRequirements = {}); /// specification of the queue to use @@ -55,11 +54,11 @@ namespace vsg /// add a compile Context for device void add(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); - /// add a compile Context for Window and associated viewport. - void add(Window& window, ref_ptr transferTask, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); + /// add a compile Context for Window. + void add(Window& window, ref_ptr transferTask, const ResourceRequirements& resourceRequirements = {}); - /// add a compile Context for Window and associated viewport. - void add(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); + /// add a compile Context for Window. + void add(Window& window, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for Window and associated View void add(Window& window, ref_ptr transferTask, ref_ptr view, const ResourceRequirements& resourceRequirements = {}); diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 64137cb8fa..284932722b 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -109,12 +109,12 @@ void CompileManager::add(ref_ptr device, const ResourceRequirements& res } } -void CompileManager::add(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) +void CompileManager::add(Window& window, const ResourceRequirements& resourceRequirements) { auto cts = takeCompileTraversals(numCompileTraversals); for (auto& ct : cts) { - ct->add(window, viewport, resourceRequirements); + ct->add(window, resourceRequirements); compileTraversals->add(ct); } diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 39a25f49c2..64e8f66bd6 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -45,12 +45,6 @@ CompileTraversal::CompileTraversal(ref_ptr device, const ResourceRequire add(device, resourceRequirements); } -CompileTraversal::CompileTraversal(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) -{ - overrideMask = vsg::MASK_ALL; - add(window, viewport, resourceRequirements); -} - CompileTraversal::CompileTraversal(const Viewer& viewer, const ResourceRequirements& resourceRequirements) { overrideMask = vsg::MASK_ALL; @@ -77,7 +71,7 @@ void CompileTraversal::add(ref_ptr device, const ResourceRequirements& r add(device, nullptr, resourceRequirements); } -void CompileTraversal::add(Window& window, ref_ptr transferTask, ref_ptr viewport, const ResourceRequirements& resourceRequirements) +void CompileTraversal::add(Window& window, ref_ptr transferTask, const ResourceRequirements& resourceRequirements) { auto device = window.getOrCreateDevice(); auto renderPass = window.getOrCreateRenderPass(); @@ -94,9 +88,9 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, r contexts.push_back(context); } -void CompileTraversal::add(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) +void CompileTraversal::add(Window& window, const ResourceRequirements& resourceRequirements) { - add(window, nullptr, viewport, resourceRequirements); + add(window, ref_ptr{}, resourceRequirements); } void CompileTraversal::add(Window& window, ref_ptr transferTask, ref_ptr view, const ResourceRequirements& resourceRequirements) From da2d31e67f35ac9088f907e2a7dc267c3b63ea46 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 12:11:57 +0000 Subject: [PATCH 08/26] Added support for shading GraphicsPipelineImplementation. --- include/vsg/state/GraphicsPipeline.h | 1 + src/vsg/state/GraphicsPipeline.cpp | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 0776890f51..81fd7f79be 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -96,6 +96,7 @@ namespace vsg virtual ~Implementation(); + GraphicsPipelineStates _pipelineStates; VkPipeline _pipeline; ref_ptr _device; diff --git a/src/vsg/state/GraphicsPipeline.cpp b/src/vsg/state/GraphicsPipeline.cpp index d8ba6d5c50..c9105a21b1 100644 --- a/src/vsg/state/GraphicsPipeline.cpp +++ b/src/vsg/state/GraphicsPipeline.cpp @@ -139,6 +139,22 @@ void GraphicsPipeline::compile(Context& context) if (!_implementation[viewID]) { + GraphicsPipelineStates combined_pipelineStates; + combined_pipelineStates.reserve(context.defaultPipelineStates.size() + pipelineStates.size() + context.overridePipelineStates.size()); + mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.defaultPipelineStates); + mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, pipelineStates); + mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.overridePipelineStates); + + for(auto& imp : _implementation) + { + if (imp && vsg::compare_pointer_container(imp->_pipelineStates, combined_pipelineStates)==0) + { + _implementation[viewID] = imp; + return; + } + } + + // compile shaders if required bool requiresShaderCompiler = false; for (const auto& shaderStage : stages) @@ -173,12 +189,6 @@ void GraphicsPipeline::compile(Context& context) shaderStage->compile(context); } - GraphicsPipelineStates combined_pipelineStates; - combined_pipelineStates.reserve(context.defaultPipelineStates.size() + pipelineStates.size() + context.overridePipelineStates.size()); - mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.defaultPipelineStates); - mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, pipelineStates); - mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.overridePipelineStates); - _implementation[viewID] = GraphicsPipeline::Implementation::create(context, context.device, context.renderPass, layout, stages, combined_pipelineStates, subpass); } } @@ -188,6 +198,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) : + _pipelineStates(pipelineStates), _device(device) { VkGraphicsPipelineCreateInfo pipelineInfo = {}; From 48b3f75583dfce015b6cf79b69fb94ca9bb12aa6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 12:18:48 +0000 Subject: [PATCH 09/26] Ran clang-format --- src/vsg/app/RecordTraversal.cpp | 2 +- src/vsg/state/GraphicsPipeline.cpp | 5 ++--- src/vsg/state/ViewportState.cpp | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index b84d28760c..7fb4ca90bd 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -579,7 +579,7 @@ void RecordTraversal::apply(const View& view) if (viewportState->slot >= _state->stateStacks.size()) { - _state->stateStacks.resize(viewportState->slot+1); + _state->stateStacks.resize(viewportState->slot + 1); // info("RecordTraversal::apply(const View& view) _state->stateStacks.size() not big enough, expanding to viewportState->slot+1."); } diff --git a/src/vsg/state/GraphicsPipeline.cpp b/src/vsg/state/GraphicsPipeline.cpp index c9105a21b1..bf89e8387d 100644 --- a/src/vsg/state/GraphicsPipeline.cpp +++ b/src/vsg/state/GraphicsPipeline.cpp @@ -145,16 +145,15 @@ void GraphicsPipeline::compile(Context& context) mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, pipelineStates); mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.overridePipelineStates); - for(auto& imp : _implementation) + for (auto& imp : _implementation) { - if (imp && vsg::compare_pointer_container(imp->_pipelineStates, combined_pipelineStates)==0) + if (imp && vsg::compare_pointer_container(imp->_pipelineStates, combined_pipelineStates) == 0) { _implementation[viewID] = imp; return; } } - // compile shaders if required bool requiresShaderCompiler = false; for (const auto& shaderStage : stages) diff --git a/src/vsg/state/ViewportState.cpp b/src/vsg/state/ViewportState.cpp index 087453c096..b4c6b6c7cd 100644 --- a/src/vsg/state/ViewportState.cpp +++ b/src/vsg/state/ViewportState.cpp @@ -28,13 +28,13 @@ ViewportState::ViewportState(const ViewportState& vs) : { } -ViewportState::ViewportState(const VkExtent2D& extent): +ViewportState::ViewportState(const VkExtent2D& extent) : ViewportState() { set(0, 0, extent.width, extent.height); } -ViewportState::ViewportState(int32_t x, int32_t y, uint32_t width, uint32_t height): +ViewportState::ViewportState(int32_t x, int32_t y, uint32_t width, uint32_t height) : ViewportState() { set(x, y, width, height); From b7aa4443b844fbb586c7dc7450d2565175fa8941 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 14:05:43 +0000 Subject: [PATCH 10/26] Changed local variable name to avoid cppcheck shadowing wrning --- include/vsg/io/stream.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/vsg/io/stream.h b/include/vsg/io/stream.h index 176e4eac4a..f0a4bbb353 100644 --- a/include/vsg/io/stream.h +++ b/include/vsg/io/stream.h @@ -287,12 +287,12 @@ namespace vsg inline std::istream& operator>>(std::istream& input, CoordinateSpace& coordinateSpace) { - std::string value; - input >> value; + std::string str; + input >> str; - if (value == "LINEAR") + if (str == "LINEAR") coordinateSpace = CoordinateSpace::LINEAR; - else if (value == "sRGB") + else if (str == "sRGB") coordinateSpace = CoordinateSpace::sRGB; else coordinateSpace = CoordinateSpace::NO_PREFERENCE; From fc79e315b1083f5f660904ff4e959f4a5c877cfb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 14:31:41 +0000 Subject: [PATCH 11/26] cppcheck fixes --- src/vsg/app/RecordTraversal.cpp | 3 +-- src/vsg/app/RenderGraph.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 7fb4ca90bd..890f71a6c4 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -588,11 +588,10 @@ void RecordTraversal::apply(const View& view) if (_viewDependentState && viewportState) { - auto& viewports = viewportState->viewports; auto& viewportData = _viewDependentState->viewportData; - if (viewportData) { + auto& viewports = viewportState->viewports; auto dest_itr = viewportData->begin(); for (auto src_itr = viewports.begin(); dest_itr != viewportData->end() && src_itr != viewports.end(); diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index fb48386f5a..48b9d5e645 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -155,7 +155,7 @@ void RenderGraph::resized() if (!windowResizeHandler) return; if (!window && !framebuffer) return; - auto activeRenderPass = getRenderPass(); + const auto activeRenderPass = getRenderPass(); if (!activeRenderPass) return; auto extent = getExtent(); From b6e9800b1375fc59b6d35f74332cf59dfb4805af Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 15:09:47 +0000 Subject: [PATCH 12/26] Bumped version for dynamic ViewportState work. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86628e60bb..c5db77b015 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7) project(vsg - VERSION 1.1.10 + VERSION 1.1.11 DESCRIPTION "VulkanSceneGraph library" LANGUAGES CXX ) From 654f24fde6343affdd0d75b3a628d36238be8bf8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 15:26:12 +0000 Subject: [PATCH 13/26] cppcheck warning fixes --- cmake/cppcheck-suppression-list.txt | 2 +- src/vsg/state/GraphicsPipeline.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 0c8b0c7a7c..9483d412b4 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -29,6 +29,7 @@ useStlAlgorithm:*/src/vsg/nodes/VertexIndexDraw.cpp useStlAlgorithm:*/src/vsg/nodes/Switch.cpp useStlAlgorithm:*/src/vsg/nodes/LOD.cpp useStlAlgorithm:*/src/vsg/state/DescriptorBuffer.cpp +useStlAlgorithm:*/src/vsg/state/GraphicsPipeline.cpp useStlAlgorithm:*/src/vsg/state/PipelineLayout.cpp useStlAlgorithm:*/src/vsg/state/StateSwitch.cpp useStlAlgorithm:*/src/vsg/state/ViewDependentState.cpp @@ -60,7 +61,6 @@ useStlAlgorithm:*/src/vsg/io/Path.cpp useStlAlgorithm:*/src/vsg/utils/PolytopeIntersector.cpp useStlAlgorithm:*/src/vsg/vk/PhysicalDevice.cpp - // suppress the warning about valid C++17 if (init; condition) usage syntaxError:*/include/vsg/core/Inherit.h syntaxError:*/src/vsg/io/AsciiOutput.cpp diff --git a/src/vsg/state/GraphicsPipeline.cpp b/src/vsg/state/GraphicsPipeline.cpp index bf89e8387d..373f1ace8b 100644 --- a/src/vsg/state/GraphicsPipeline.cpp +++ b/src/vsg/state/GraphicsPipeline.cpp @@ -145,7 +145,7 @@ void GraphicsPipeline::compile(Context& context) mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, pipelineStates); mergeGraphicsPipelineStates(context.mask, combined_pipelineStates, context.overridePipelineStates); - for (auto& imp : _implementation) + for (const auto& imp : _implementation) { if (imp && vsg::compare_pointer_container(imp->_pipelineStates, combined_pipelineStates) == 0) { From ccacf18a36c9239eef3913345928b0a7265848ea Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 16:07:26 +0000 Subject: [PATCH 14/26] cppcheck warning fix. --- src/vsg/utils/GraphicsPipelineConfigurator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 13ecf03394..1a032b95f1 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -167,7 +167,7 @@ bool DescriptorConfigurator::assignTexture(const std::string& name, const ImageI // set up bindings if (!textureBinding.define.empty()) defines.insert(textureBinding.define); - for (auto& imageInfo : imageInfoList) + for (const auto& imageInfo : imageInfoList) { if (imageInfo->imageView && imageInfo->imageView->image) { From 8b248aaa34437a4aae5bcc54dcefb7be844259a8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 16:54:31 +0000 Subject: [PATCH 15/26] Fixed typo --- src/vsg/utils/GraphicsPipelineConfigurator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 1a032b95f1..698139c635 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -78,9 +78,9 @@ struct AssignGraphicsPipelineStates : public vsg::Visitor vertexInputState = VertexInputState::create(ias); config->pipelineStates.push_back(vertexInputState); } - void apply(vsg::ViewportState& ias) override + void apply(vsg::ViewportState& vs) override { - viewportState = ViewportState::create(ias); + viewportState = ViewportState::create(vs); config->pipelineStates.push_back(viewportState); } }; From a29be81c25b7f68e27766eed715c0023ef0b3757 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Feb 2025 18:11:08 +0000 Subject: [PATCH 16/26] Added assignment of ViewportState to pre-render Cameras. --- src/vsg/state/ViewDependentState.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 2c41804876..50bb8e4848 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -394,6 +394,8 @@ void ViewDependentState::init(ResourceRequirements& requirements) Mask shadowMask = 0x1; // TODO: do we inherit from main scene? how? + auto viewportState = ViewportState::create(VkExtent2D{shadowWidth, shadowHeight}); + ref_ptr first_view; shadowMaps.resize(maxShadowMaps); for (auto& shadowMap : shadowMaps) @@ -411,6 +413,7 @@ void ViewDependentState::init(ResourceRequirements& requirements) shadowMap.view->mask = shadowMask; shadowMap.view->camera = Camera::create(); shadowMap.view->addChild(tcon); + shadowMap.view->camera->viewportState = viewportState; shadowMap.renderGraph = RenderGraph::create(); shadowMap.renderGraph->addChild(shadowMap.view); From 83ff1074b47c44ea5749363a1a7f60f32e50b65a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 10:20:25 +0000 Subject: [PATCH 17/26] Added push/pop of RenderGraph's area as ViewportState to enble rendering without use of vsg::View. --- include/vsg/vk/State.h | 37 +++++++++++++++++++ src/vsg/app/RecordTraversal.cpp | 63 ++++++++++++++------------------- src/vsg/app/RenderGraph.cpp | 7 ++++ 3 files changed, 70 insertions(+), 37 deletions(-) diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index 49b7549a6f..9e307aa831 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -299,6 +299,43 @@ namespace vsg } } + inline void push(const StateCommands& commands) + { + for (auto& command : commands) + { + stateStacks[command->slot].push(command); + } + dirty = true; + } + + inline void pop(const StateCommands& commands) + { + for (const auto& command : commands) + { + stateStacks[command->slot].pop(); + } + dirty = true; + } + + inline void push(ref_ptr command) + { + // add resize when required - slower but catches cases where State hasn't been initialized correctly yet. + if (command->slot >= stateStacks.size()) + { + stateStacks.resize(command->slot + 1); + } + + stateStacks[command->slot].push(command); + dirty = true; + } + + inline void pop(ref_ptr command) + { + stateStacks[command->slot].pop(); + dirty = true; + } + + inline void pushFrustum() { _frustumStack.push(Frustum(_frustumProjected, modelviewMatrixStack.top())); diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 890f71a6c4..0d19442a9e 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -484,19 +484,11 @@ void RecordTraversal::apply(const StateGroup& stateGroup) //debug("Visiting StateGroup"); - for (auto& command : stateGroup.stateCommands) - { - _state->stateStacks[command->slot].push(command); - } - _state->dirty = true; + _state->push(stateGroup.stateCommands); stateGroup.traverse(*this); - for (const auto& command : stateGroup.stateCommands) - { - _state->stateStacks[command->slot].pop(); - } - _state->dirty = true; + _state->pop(stateGroup.stateCommands); } void RecordTraversal::apply(const Commands& commands) @@ -575,43 +567,40 @@ void RecordTraversal::apply(const View& view) _state->inheritViewForLODScaling = (view.features & INHERIT_VIEWPOINT) != 0; _state->setProjectionAndViewMatrix(view.camera->projectionMatrix->transform(), view.camera->viewMatrix->transform()); - auto& viewportState = view.camera->viewportState; - - if (viewportState->slot >= _state->stateStacks.size()) + if (const auto& viewportState = view.camera->viewportState) { - _state->stateStacks.resize(viewportState->slot + 1); - // info("RecordTraversal::apply(const View& view) _state->stateStacks.size() not big enough, expanding to viewportState->slot+1."); - } + _state->push(viewportState); - _state->stateStacks[viewportState->slot].push(viewportState); - _state->dirty = true; - - if (_viewDependentState && viewportState) - { - auto& viewportData = _viewDependentState->viewportData; - if (viewportData) + if (_viewDependentState) { - auto& viewports = viewportState->viewports; - auto dest_itr = viewportData->begin(); - for (auto src_itr = viewports.begin(); - dest_itr != viewportData->end() && src_itr != viewports.end(); - ++dest_itr, ++src_itr) + auto& viewportData = _viewDependentState->viewportData; + if (viewportData) { - auto& dest_viewport = *dest_itr; - vec4 src_viewport(src_itr->x, src_itr->y, src_itr->width, src_itr->height); - if (dest_viewport != src_viewport) + auto& viewports = viewportState->viewports; + auto dest_itr = viewportData->begin(); + for (auto src_itr = viewports.begin(); + dest_itr != viewportData->end() && src_itr != viewports.end(); + ++dest_itr, ++src_itr) { - dest_viewport = src_viewport; - viewportData->dirty(); + auto& dest_viewport = *dest_itr; + vec4 src_viewport(src_itr->x, src_itr->y, src_itr->width, src_itr->height); + if (dest_viewport != src_viewport) + { + dest_viewport = src_viewport; + viewportData->dirty(); + } } } } - } - view.traverse(*this); + view.traverse(*this); - _state->stateStacks[viewportState->slot].pop(); - _state->dirty = true; + _state->pop(viewportState); + } + else + { + view.traverse(*this); + } } else { diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index 48b9d5e645..bfabac4a07 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -138,16 +138,23 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const , ", renderArea.extent.width = ", renderArea.extent.width, ", renderArea.extent.height = ", renderArea.extent.height); #endif + renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); VkCommandBuffer vk_commandBuffer = *(recordTraversal.getState()->_commandBuffer); vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents); + auto viewportState = ViewportState::create(renderArea.offset.x, renderArea.offset.y, renderArea.extent.width, renderArea.extent.height); + recordTraversal.getState()->push(viewportState); + // traverse the subgraph to place commands into the command buffer. traverse(recordTraversal); + recordTraversal.getState()->pop(viewportState); + vkCmdEndRenderPass(vk_commandBuffer); + } void RenderGraph::resized() From 462d86a7c503590839a7a1150d98f36ce64c1dcf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 10:22:46 +0000 Subject: [PATCH 18/26] Ran clang-format --- include/vsg/vk/State.h | 1 - src/vsg/app/RecordTraversal.cpp | 4 ++-- src/vsg/app/RenderGraph.cpp | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index 9e307aa831..6d9b75e7f5 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -335,7 +335,6 @@ namespace vsg dirty = true; } - inline void pushFrustum() { _frustumStack.push(Frustum(_frustumProjected, modelviewMatrixStack.top())); diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 0d19442a9e..2254b04bfa 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -579,8 +579,8 @@ void RecordTraversal::apply(const View& view) auto& viewports = viewportState->viewports; auto dest_itr = viewportData->begin(); for (auto src_itr = viewports.begin(); - dest_itr != viewportData->end() && src_itr != viewports.end(); - ++dest_itr, ++src_itr) + dest_itr != viewportData->end() && src_itr != viewports.end(); + ++dest_itr, ++src_itr) { auto& dest_viewport = *dest_itr; vec4 src_viewport(src_itr->x, src_itr->y, src_itr->width, src_itr->height); diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index bfabac4a07..4af84a6a39 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -138,7 +138,6 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const , ", renderArea.extent.width = ", renderArea.extent.width, ", renderArea.extent.height = ", renderArea.extent.height); #endif - renderPassInfo.clearValueCount = static_cast(clearValues.size()); renderPassInfo.pClearValues = clearValues.data(); @@ -154,7 +153,6 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const recordTraversal.getState()->pop(viewportState); vkCmdEndRenderPass(vk_commandBuffer); - } void RenderGraph::resized() From 12862b167729c329b739fbed2ede4bf06b34aa52 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 11:23:44 +0000 Subject: [PATCH 19/26] Added compile with ViewportState. --- src/vsg/app/CompileTraversal.cpp | 1 + src/vsg/state/GraphicsPipeline.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 64e8f66bd6..2180c3af92 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -399,6 +399,7 @@ void CompileTraversal::apply(View& view) } // assign view specific pipeline states + mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, view.camera->viewportState); mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, view.overridePipelineStates); view.traverse(*this); diff --git a/src/vsg/state/GraphicsPipeline.cpp b/src/vsg/state/GraphicsPipeline.cpp index 373f1ace8b..b81914aa83 100644 --- a/src/vsg/state/GraphicsPipeline.cpp +++ b/src/vsg/state/GraphicsPipeline.cpp @@ -54,7 +54,7 @@ void GraphicsPipelineState::write(Output& output) const void vsg::mergeGraphicsPipelineStates(Mask mask, GraphicsPipelineStates& dest_PipelineStates, ref_ptr src_PipelineState) { - if ((mask & src_PipelineState->mask) == 0) return; + if (!src_PipelineState || (mask & src_PipelineState->mask) == 0) return; // replace any entries in the dest_PipelineStates that have the same type as src_PipelineState for (auto& original_pipelineState : dest_PipelineStates) From 7742fb5078dc73908add0388d4d508e4eb5f3c0b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 12:03:41 +0000 Subject: [PATCH 20/26] Added ViewportState to RenderGraph. --- include/vsg/app/RenderGraph.h | 5 ++++- src/vsg/app/CompileTraversal.cpp | 3 +++ src/vsg/app/RenderGraph.cpp | 10 +++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/vsg/app/RenderGraph.h b/include/vsg/app/RenderGraph.h index b72c68ae12..e4ea4102f5 100644 --- a/include/vsg/app/RenderGraph.h +++ b/include/vsg/app/RenderGraph.h @@ -47,9 +47,12 @@ namespace vsg /// Get the Extent2D of the attached Framebuffer or Window. VkExtent2D getExtent() const; - /// RenderArea settings for VkRenderPassBeginInfo.renderArea passed to the vkCmdBeginRenderPass, usually matches the ViewportState's scissor + /// RenderArea settings for VkRenderPassBeginInfo.renderArea passed to the vkCmdBeginRenderPass VkRect2D renderArea; + // Default ViewportState to use for graphics pipelines under this RenderGraph, this be will synced with the renderArea. + ref_ptr viewportState; + /// RenderPass to use passed to the vkCmdBeginRenderPass in place of the framebuffer's or window's renderPass. renderPass must be compatible with the render pass used to create the window or framebuffer. ref_ptr renderPass; diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 2180c3af92..40f2740e54 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -356,12 +356,15 @@ void CompileTraversal::apply(RenderGraph& renderGraph) auto previousDefaultPipelineStates = context->defaultPipelineStates; auto previousOverridePipelineStates = context->overridePipelineStates; + mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, renderGraph.viewportState); + context->renderPass = renderGraph.getRenderPass(); if (context->renderPass) { mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); } + renderGraph.traverse(*this); // restore previous values diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index 4af84a6a39..ef83ec7111 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -22,14 +22,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; RenderGraph::RenderGraph() : + viewportState(ViewportState::create()), windowResizeHandler(WindowResizeHandler::create()) { } RenderGraph::RenderGraph(ref_ptr in_window, ref_ptr in_view) : - window(in_window), - windowResizeHandler(WindowResizeHandler::create()) + RenderGraph() { + window = in_window; if (in_view) { @@ -48,6 +49,8 @@ RenderGraph::RenderGraph(ref_ptr in_window, ref_ptr in_view) : renderArea.extent = window->extent2D(); } + viewportState->set(renderArea.offset.x, renderArea.offset.y, renderArea.extent.width, renderArea.extent.height); + // set up the clearValues based on the RenderPass's attachments. setClearValues(window->clearColor(), VkClearDepthStencilValue{0.0f, 0}); } @@ -144,7 +147,8 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const VkCommandBuffer vk_commandBuffer = *(recordTraversal.getState()->_commandBuffer); vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents); - auto viewportState = ViewportState::create(renderArea.offset.x, renderArea.offset.y, renderArea.extent.width, renderArea.extent.height); + // sync the viewportState and push + viewportState->set(renderArea.offset.x, renderArea.offset.y, renderArea.extent.width, renderArea.extent.height); recordTraversal.getState()->push(viewportState); // traverse the subgraph to place commands into the command buffer. From 69d5e45967c577479c64241ebb194a991135406a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 12:07:47 +0000 Subject: [PATCH 21/26] Ran clang-format. --- src/vsg/app/CompileTraversal.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 40f2740e54..95fb299550 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -364,7 +364,6 @@ void CompileTraversal::apply(RenderGraph& renderGraph) mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); } - renderGraph.traverse(*this); // restore previous values From 74fd8977c60ec904e9a20cfbe639f8638197daf2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 12:25:26 +0000 Subject: [PATCH 22/26] Updated built-in ShaderSet. --- src/vsg/text/shaders/text_ShaderSet.cpp | 2 +- src/vsg/utils/shaders/flat_ShaderSet.cpp | 2 +- src/vsg/utils/shaders/pbr_ShaderSet.cpp | 2 +- src/vsg/utils/shaders/phong_ShaderSet.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vsg/text/shaders/text_ShaderSet.cpp b/src/vsg/text/shaders/text_ShaderSet.cpp index 33c66da1a7..a106043468 100644 --- a/src/vsg/text/shaders/text_ShaderSet.cpp +++ b/src/vsg/text/shaders/text_ShaderSet.cpp @@ -2,7 +2,7 @@ #include static auto text_ShaderSet = []() { static const uint8_t data[] = { -35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 48, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, +35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 49, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 101, 116, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 116, 97, 103, 101, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 3, 0, 0, 0, 17, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 77, 111, 100, 117, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 245, 16, 0, 0, diff --git a/src/vsg/utils/shaders/flat_ShaderSet.cpp b/src/vsg/utils/shaders/flat_ShaderSet.cpp index 664f8afb65..e29957694c 100644 --- a/src/vsg/utils/shaders/flat_ShaderSet.cpp +++ b/src/vsg/utils/shaders/flat_ShaderSet.cpp @@ -2,7 +2,7 @@ #include static auto flat_ShaderSet = []() { static const uint8_t data[] = { -35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 48, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, +35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 49, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 101, 116, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 116, 97, 103, 101, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 3, 0, 0, 0, 17, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 77, 111, 100, 117, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 71, 17, 0, 0, diff --git a/src/vsg/utils/shaders/pbr_ShaderSet.cpp b/src/vsg/utils/shaders/pbr_ShaderSet.cpp index ab85e9eb62..d6e9695f89 100644 --- a/src/vsg/utils/shaders/pbr_ShaderSet.cpp +++ b/src/vsg/utils/shaders/pbr_ShaderSet.cpp @@ -2,7 +2,7 @@ #include static auto pbr_ShaderSet = []() { static const uint8_t data[] = { -35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 48, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, +35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 49, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 101, 116, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 116, 97, 103, 101, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 3, 0, 0, 0, 17, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 77, 111, 100, 117, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 71, 17, 0, 0, diff --git a/src/vsg/utils/shaders/phong_ShaderSet.cpp b/src/vsg/utils/shaders/phong_ShaderSet.cpp index d1cb88e04c..2575ae8a63 100644 --- a/src/vsg/utils/shaders/phong_ShaderSet.cpp +++ b/src/vsg/utils/shaders/phong_ShaderSet.cpp @@ -2,7 +2,7 @@ #include static auto phong_ShaderSet = []() { static const uint8_t data[] = { -35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 48, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, +35, 118, 115, 103, 98, 32, 49, 46, 49, 46, 49, 49, 10, 1, 0, 0, 0, 14, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 101, 116, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 83, 116, 97, 103, 101, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 3, 0, 0, 0, 17, 0, 0, 0, 118, 115, 103, 58, 58, 83, 104, 97, 100, 101, 114, 77, 111, 100, 117, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 71, 17, 0, 0, From 1fac1761e48e2a56cf7259a7522742c0e49362a8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Feb 2025 15:14:53 +0000 Subject: [PATCH 23/26] Fixed Visitor/ConstVisitor support for GraphicsPipelineStates Added support for checking ViewportState's slot number when calculating resource requirements. --- include/vsg/vk/ResourceRequirements.h | 1 + include/vsg/vk/State.h | 6 ------ src/vsg/app/RenderGraph.cpp | 3 +-- src/vsg/core/ConstVisitor.cpp | 2 +- src/vsg/core/Visitor.cpp | 2 +- src/vsg/vk/ResourceRequirements.cpp | 8 +++++++- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/vsg/vk/ResourceRequirements.h b/include/vsg/vk/ResourceRequirements.h index dd1a0b28b2..9a1df52bca 100644 --- a/include/vsg/vk/ResourceRequirements.h +++ b/include/vsg/vk/ResourceRequirements.h @@ -130,6 +130,7 @@ namespace vsg void apply(const DescriptorImage& descriptorImage) override; void apply(const PagedLOD& plod) override; void apply(const Light& light) override; + void apply(const RenderGraph& rg) override; void apply(const View& view) override; void apply(const DepthSorted& depthSorted) override; void apply(const Layer& layer) override; diff --git a/include/vsg/vk/State.h b/include/vsg/vk/State.h index 6d9b75e7f5..b82f4eabc3 100644 --- a/include/vsg/vk/State.h +++ b/include/vsg/vk/State.h @@ -319,12 +319,6 @@ namespace vsg inline void push(ref_ptr command) { - // add resize when required - slower but catches cases where State hasn't been initialized correctly yet. - if (command->slot >= stateStacks.size()) - { - stateStacks.resize(command->slot + 1); - } - stateStacks[command->slot].push(command); dirty = true; } diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index ef83ec7111..2803c03479 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -164,8 +164,7 @@ void RenderGraph::resized() if (!windowResizeHandler) return; if (!window && !framebuffer) return; - const auto activeRenderPass = getRenderPass(); - if (!activeRenderPass) return; + if (!getRenderPass()) return; auto extent = getExtent(); diff --git a/src/vsg/core/ConstVisitor.cpp b/src/vsg/core/ConstVisitor.cpp index ffe3fca006..82a576d6a2 100644 --- a/src/vsg/core/ConstVisitor.cpp +++ b/src/vsg/core/ConstVisitor.cpp @@ -818,7 +818,7 @@ void ConstVisitor::apply(const RayTracingPipeline& value) } void ConstVisitor::apply(const GraphicsPipelineState& value) { - apply(static_cast(value)); + apply(static_cast(value)); } void ConstVisitor::apply(const ShaderStage& value) { diff --git a/src/vsg/core/Visitor.cpp b/src/vsg/core/Visitor.cpp index 9a274f3dfe..c0fb6d98a6 100644 --- a/src/vsg/core/Visitor.cpp +++ b/src/vsg/core/Visitor.cpp @@ -818,7 +818,7 @@ void Visitor::apply(RayTracingPipeline& value) } void Visitor::apply(GraphicsPipelineState& value) { - apply(static_cast(value)); + apply(static_cast(value)); } void Visitor::apply(ShaderStage& value) { diff --git a/src/vsg/vk/ResourceRequirements.cpp b/src/vsg/vk/ResourceRequirements.cpp index aacda91060..b9947f2778 100644 --- a/src/vsg/vk/ResourceRequirements.cpp +++ b/src/vsg/vk/ResourceRequirements.cpp @@ -155,7 +155,6 @@ void CollectResourceRequirements::apply(const PagedLOD& plod) void CollectResourceRequirements::apply(const StateCommand& stateCommand) { if (stateCommand.slot > requirements.maxSlot) requirements.maxSlot = stateCommand.slot; - stateCommand.traverse(*this); } @@ -212,8 +211,15 @@ void CollectResourceRequirements::apply(const Light& light) requirements.viewDetailsStack.top().lights.insert(&light); } +void CollectResourceRequirements::apply(const RenderGraph& rg) +{ + if (rg.viewportState) rg.viewportState->accept(*this); + rg.traverse(*this); +} + void CollectResourceRequirements::apply(const View& view) { + if (view.camera && view.camera->viewportState) view.camera->viewportState->accept(*this); if (auto itr = requirements.views.find(&view); itr != requirements.views.end()) { From 8a982095a56fcde8e0f6d7ba4308df0ef87a68b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 12 Feb 2025 09:50:22 +0000 Subject: [PATCH 24/26] Revert "Simplified CompileManager and CompileTraversal removing ViewportState centric methods that are no longer required." This reverts commit 9d17041fe0a871da90c7023a99b5aa3aacc18b5b. --- include/vsg/app/CompileManager.h | 2 +- include/vsg/app/CompileTraversal.h | 9 +++++---- src/vsg/app/CompileManager.cpp | 4 ++-- src/vsg/app/CompileTraversal.cpp | 12 +++++++++--- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index 7b403433ab..5f28abd71a 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -49,7 +49,7 @@ namespace vsg void add(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for Window and associated viewport. - void add(Window& window, const ResourceRequirements& resourceRequirements = {}); + void add(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for View void add(Window& window, ref_ptr view, const ResourceRequirements& resourceRequirements = {}); diff --git a/include/vsg/app/CompileTraversal.h b/include/vsg/app/CompileTraversal.h index 235b0cb5e9..fa9fdf1809 100644 --- a/include/vsg/app/CompileTraversal.h +++ b/include/vsg/app/CompileTraversal.h @@ -36,6 +36,7 @@ namespace vsg CompileTraversal() { overrideMask = vsg::MASK_ALL; } CompileTraversal(const CompileTraversal& ct); explicit CompileTraversal(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); + explicit CompileTraversal(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); explicit CompileTraversal(const Viewer& viewer, const ResourceRequirements& resourceRequirements = {}); /// specification of the queue to use @@ -54,11 +55,11 @@ namespace vsg /// add a compile Context for device void add(ref_ptr device, const ResourceRequirements& resourceRequirements = {}); - /// add a compile Context for Window. - void add(Window& window, ref_ptr transferTask, const ResourceRequirements& resourceRequirements = {}); + /// add a compile Context for Window and associated viewport. + void add(Window& window, ref_ptr transferTask, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); - /// add a compile Context for Window. - void add(Window& window, const ResourceRequirements& resourceRequirements = {}); + /// add a compile Context for Window and associated viewport. + void add(Window& window, ref_ptr viewport = {}, const ResourceRequirements& resourceRequirements = {}); /// add a compile Context for Window and associated View void add(Window& window, ref_ptr transferTask, ref_ptr view, const ResourceRequirements& resourceRequirements = {}); diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 284932722b..64137cb8fa 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -109,12 +109,12 @@ void CompileManager::add(ref_ptr device, const ResourceRequirements& res } } -void CompileManager::add(Window& window, const ResourceRequirements& resourceRequirements) +void CompileManager::add(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) { auto cts = takeCompileTraversals(numCompileTraversals); for (auto& ct : cts) { - ct->add(window, resourceRequirements); + ct->add(window, viewport, resourceRequirements); compileTraversals->add(ct); } diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 95fb299550..a92f95950f 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -45,6 +45,12 @@ CompileTraversal::CompileTraversal(ref_ptr device, const ResourceRequire add(device, resourceRequirements); } +CompileTraversal::CompileTraversal(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) +{ + overrideMask = vsg::MASK_ALL; + add(window, viewport, resourceRequirements); +} + CompileTraversal::CompileTraversal(const Viewer& viewer, const ResourceRequirements& resourceRequirements) { overrideMask = vsg::MASK_ALL; @@ -71,7 +77,7 @@ void CompileTraversal::add(ref_ptr device, const ResourceRequirements& r add(device, nullptr, resourceRequirements); } -void CompileTraversal::add(Window& window, ref_ptr transferTask, const ResourceRequirements& resourceRequirements) +void CompileTraversal::add(Window& window, ref_ptr transferTask, ref_ptr viewport, const ResourceRequirements& resourceRequirements) { auto device = window.getOrCreateDevice(); auto renderPass = window.getOrCreateRenderPass(); @@ -88,9 +94,9 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, c contexts.push_back(context); } -void CompileTraversal::add(Window& window, const ResourceRequirements& resourceRequirements) +void CompileTraversal::add(Window& window, ref_ptr viewport, const ResourceRequirements& resourceRequirements) { - add(window, ref_ptr{}, resourceRequirements); + add(window, nullptr, viewport, resourceRequirements); } void CompileTraversal::add(Window& window, ref_ptr transferTask, ref_ptr view, const ResourceRequirements& resourceRequirements) From fdf06f546150e42f6091a9cec095937d7dc671ac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 12 Feb 2025 10:44:57 +0000 Subject: [PATCH 25/26] Revert "Removed passing ViewportState to compile traversal." This reverts commit 266560e4795a4264b7683c21176dca3ff0a7979e. --- src/vsg/app/CompileTraversal.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index a92f95950f..387909821f 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -89,6 +89,11 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, r context->graphicsQueue = device->getQueue(queueFamily, queueFamilyIndex); context->transferTask = transferTask; + if (viewport) + context->defaultPipelineStates.emplace_back(viewport); + else + context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(window.extent2D())); + if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) context->overridePipelineStates.emplace_back(MultisampleState::create(renderPass->maxSamples)); contexts.push_back(context); @@ -115,6 +120,11 @@ void CompileTraversal::add(Window& window, ref_ptr transferTask, r context->overridePipelineStates.insert(context->overridePipelineStates.end(), view->overridePipelineStates.begin(), view->overridePipelineStates.end()); + if (view->camera && view->camera->viewportState) + context->defaultPipelineStates.emplace_back(view->camera->viewportState); + else + context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(window.extent2D())); + context->view = view.get(); context->viewID = view->viewID; context->viewDependentState = view->viewDependentState; @@ -149,6 +159,11 @@ void CompileTraversal::add(ref_ptr context, Framebuffer& framebuffer, r if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) context->overridePipelineStates.emplace_back(vsg::MultisampleState::create(renderPass->maxSamples)); context->overridePipelineStates.insert(context->overridePipelineStates.end(), view->overridePipelineStates.begin(), view->overridePipelineStates.end()); + if (view->camera && view->camera->viewportState) + context->defaultPipelineStates.emplace_back(view->camera->viewportState); + else + context->defaultPipelineStates.emplace_back(vsg::ViewportState::create(framebuffer.extent2D())); + context->view = view.get(); context->viewID = view->viewID; context->viewDependentState = view->viewDependentState; @@ -337,6 +352,15 @@ void CompileTraversal::apply(SecondaryCommandGraph& secondaryCommandGraph) context->renderPass = renderPass; + if (secondaryCommandGraph.window) + { + mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(secondaryCommandGraph.window->extent2D())); + } + else if (secondaryCommandGraph.framebuffer) + { + mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, ViewportState::create(secondaryCommandGraph.framebuffer->extent2D())); + } + if (renderPass) { mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); @@ -365,6 +389,7 @@ void CompileTraversal::apply(RenderGraph& renderGraph) mergeGraphicsPipelineStates(context->mask, context->defaultPipelineStates, renderGraph.viewportState); context->renderPass = renderGraph.getRenderPass(); + if (context->renderPass) { mergeGraphicsPipelineStates(context->mask, context->overridePipelineStates, MultisampleState::create(context->renderPass->maxSamples)); From 68efcf53675155531308e5c52ca9ef376d213e11 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 12 Feb 2025 13:26:44 +0000 Subject: [PATCH 26/26] Upped the ViewportState::slot to 8 to make it less likely that it'll use the same slot as BindDescriptorSet entries. --- src/vsg/state/ViewportState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/state/ViewportState.cpp b/src/vsg/state/ViewportState.cpp index b4c6b6c7cd..c2f4a25a81 100644 --- a/src/vsg/state/ViewportState.cpp +++ b/src/vsg/state/ViewportState.cpp @@ -18,7 +18,7 @@ using namespace vsg; ViewportState::ViewportState() { - slot = 3; + slot = 8; } ViewportState::ViewportState(const ViewportState& vs) :