Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use dynamic viewport and scissor by default #1268

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions include/vsg/app/WindowResizeHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Visitor, UpdateGraphicsPipelines>
{
public:
Expand All @@ -43,7 +44,6 @@ namespace vsg
class VSG_DECLSPEC WindowResizeHandler : public Inherit<Visitor, WindowResizeHandler>
{
public:
ref_ptr<Context> context;
VkRect2D renderArea;
VkExtent2D previous_extent;
VkExtent2D new_extent;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions include/vsg/state/DynamicState.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<GraphicsPipelineState, DynamicState>
{
public:
Expand Down
6 changes: 6 additions & 0 deletions include/vsg/vk/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ namespace vsg
MatrixStack projectionMatrixStack{0};
MatrixStack modelviewMatrixStack{64};

StateStack<Command> scissorStack{};
StateStack<Command> viewportStack{};

void setInhertiedViewProjectionAndViewMatrix(const dmat4& projMatrix, const dmat4& viewMatrix)
{
inheritedProjectionMatrix = projMatrix;
Expand Down Expand Up @@ -292,6 +295,9 @@ namespace vsg
stateStack.record(*_commandBuffer);
}

scissorStack.record(*_commandBuffer);
viewportStack.record(*_commandBuffer);

projectionMatrixStack.record(*_commandBuffer);
modelviewMatrixStack.record(*_commandBuffer);

Expand Down
15 changes: 15 additions & 0 deletions src/vsg/app/CommandGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include <vsg/app/CommandGraph.h>
#include <vsg/app/RenderGraph.h>
#include <vsg/app/View.h>
#include <vsg/commands/SetScissor.h>
#include <vsg/commands/SetViewport.h>
#include <vsg/io/DatabasePager.h>
#include <vsg/state/ViewDependentState.h>
#include <vsg/ui/ApplicationEvent.h>
Expand Down Expand Up @@ -119,6 +121,13 @@ void CommandGraph::record(ref_ptr<RecordedCommandBuffers> 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<float>(extent.width), static_cast<float>(extent.height), 0.0f, 1.0f}}));
}

// or select index when maps to a dormant CommandBuffer
VkCommandBuffer vk_commandBuffer = *commandBuffer;

Expand All @@ -138,6 +147,12 @@ void CommandGraph::record(ref_ptr<RecordedCommandBuffers> recordedCommandBuffers

vkEndCommandBuffer(vk_commandBuffer);

if (framebuffer || window)
{
recordTraversal->getState()->scissorStack.pop();
recordTraversal->getState()->viewportStack.pop();
}

recordedCommandBuffers->add(submitOrder, commandBuffer);
}

Expand Down
34 changes: 24 additions & 10 deletions src/vsg/app/RecordTraversal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include <vsg/app/View.h>
#include <vsg/commands/Command.h>
#include <vsg/commands/Commands.h>
#include <vsg/commands/SetScissor.h>
#include <vsg/commands/SetViewport.h>
#include <vsg/io/DatabasePager.h>
#include <vsg/io/Logger.h>
#include <vsg/io/Options.h>
Expand Down Expand Up @@ -541,27 +543,39 @@ 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)
_state->scissorStack.push(vsg::SetScissor::create(0, view.camera->viewportState->scissors));
_state->viewportStack.push(vsg::SetViewport::create(0, viewports));

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();
}
}
}
}

view.traverse(*this);

if (_viewDependentState && view.camera->viewportState)
{
_state->scissorStack.pop();
_state->viewportStack.pop();
}
}
else
{
Expand Down
28 changes: 14 additions & 14 deletions src/vsg/app/RenderGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI

#include <vsg/app/RenderGraph.h>
#include <vsg/app/View.h>
#include <vsg/commands/SetScissor.h>
#include <vsg/commands/SetViewport.h>
#include <vsg/io/Logger.h>
#include <vsg/io/Options.h>
#include <vsg/lighting/Light.h>
Expand Down Expand Up @@ -142,13 +144,25 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const
renderPassInfo.clearValueCount = static_cast<uint32_t>(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<float>(extent.width), static_cast<float>(extent.height), 0.0f, 1.0f}}));
}

VkCommandBuffer vk_commandBuffer = *(recordTraversal.getState()->_commandBuffer);
vkCmdBeginRenderPass(vk_commandBuffer, &renderPassInfo, contents);

// traverse the subgraph to place commands into the command buffer.
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()
Expand All @@ -159,27 +173,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);
Expand Down
15 changes: 15 additions & 0 deletions src/vsg/app/SecondaryCommandGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include <vsg/app/RenderGraph.h>
#include <vsg/app/View.h>
#include <vsg/commands/ExecuteCommands.h>
#include <vsg/commands/SetScissor.h>
#include <vsg/commands/SetViewport.h>
#include <vsg/io/DatabasePager.h>
#include <vsg/lighting/Light.h>
#include <vsg/ui/ApplicationEvent.h>
Expand Down Expand Up @@ -155,12 +157,25 @@ void SecondaryCommandGraph::record(ref_ptr<RecordedCommandBuffers> 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<float>(extent.width), static_cast<float>(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)
{
Expand Down
40 changes: 0 additions & 40 deletions src/vsg/app/WindowResizeHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -144,8 +110,6 @@ void WindowResizeHandler::apply(vsg::View& view)
{
if (!visit(&view)) return;

context->viewID = view.viewID;

if (!view.camera)
{
view.traverse(*this);
Expand Down Expand Up @@ -178,9 +142,5 @@ void WindowResizeHandler::apply(vsg::View& view)
}
}

context->defaultPipelineStates.emplace_back(viewportState);

view.traverse(*this);

context->defaultPipelineStates.pop_back();
}
3 changes: 2 additions & 1 deletion src/vsg/state/DynamicState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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})
{
}

Expand Down
3 changes: 3 additions & 0 deletions src/vsg/vk/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include <vsg/nodes/QuadGroup.h>
#include <vsg/nodes/StateGroup.h>
#include <vsg/state/DescriptorSet.h>
#include <vsg/state/DynamicState.h>
#include <vsg/vk/CommandBuffer.h>
#include <vsg/vk/Context.h>
#include <vsg/vk/DescriptorPools.h>
Expand Down Expand Up @@ -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) :
Expand Down