From e472050f36182f87698b86703736d192bb359a80 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 28 Feb 2019 15:45:59 +0100 Subject: [PATCH] - use dynamic state for viewport and scissor --- .../vulkan/renderer/vk_renderpass.cpp | 10 ++++ .../vulkan/renderer/vk_renderstate.cpp | 59 +++++++++++++++++++ .../vulkan/renderer/vk_renderstate.h | 6 ++ src/rendering/vulkan/system/vk_builders.h | 18 ++++-- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp index cb6b80a4a7..c38f626f46 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -157,6 +157,16 @@ void VkRenderPassSetup::CreatePipeline() builder.addVertexAttribute(5, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(FFlatVertex, x)); #endif + builder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT); + builder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR); + // builder.addDynamicState(VK_DYNAMIC_STATE_LINE_WIDTH); + // builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS); + // builder.addDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS); + // builder.addDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS); + // builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK); + // builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK); + // builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE); + builder.setViewport(0.0f, 0.0f, (float)SCREENWIDTH, (float)SCREENHEIGHT); builder.setScissor(0, 0, SCREENWIDTH, SCREENHEIGHT); builder.setAlphaBlendMode(); diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index c73b233f28..b56dd07665 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -77,6 +77,9 @@ void VkRenderState::SetDepthFunc(int func) void VkRenderState::SetDepthRange(float min, float max) { + mViewportDepthMin = min; + mViewportDepthMax = max; + mViewportChanged = true; } void VkRenderState::SetColorMask(bool r, bool g, bool b, bool a) @@ -109,10 +112,20 @@ void VkRenderState::EnableStencil(bool on) void VkRenderState::SetScissor(int x, int y, int w, int h) { + mScissorX = x; + mScissorY = y; + mScissorWidth = w; + mScissorHeight = h; + mScissorChanged = true; } void VkRenderState::SetViewport(int x, int y, int w, int h) { + mViewportX = x; + mViewportY = y; + mViewportWidth = w; + mViewportHeight = h; + mViewportChanged = true; } void VkRenderState::EnableDepthTest(bool on) @@ -139,6 +152,8 @@ void VkRenderState::Apply(int dt) { mCommandBuffer = fb->GetDrawCommands(); changingRenderPass = true; + mScissorChanged = true; + mViewportChanged = true; } else if (changingRenderPass) { @@ -157,6 +172,50 @@ void VkRenderState::Apply(int dt) mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); } + if (mScissorChanged) + { + VkRect2D scissor; + if (mScissorWidth >= 0) + { + scissor.offset.x = mScissorX; + scissor.offset.y = mScissorY; + scissor.extent.width = mScissorWidth; + scissor.extent.height = mScissorHeight; + } + else + { + scissor.offset.x = 0; + scissor.offset.y = 0; + scissor.extent.width = SCREENWIDTH; + scissor.extent.height = SCREENHEIGHT; + } + mCommandBuffer->setScissor(0, 1, &scissor); + mScissorChanged = false; + } + + if (mViewportChanged) + { + VkViewport viewport; + if (mViewportWidth >= 0) + { + viewport.x = (float)mViewportX; + viewport.y = (float)mViewportY; + viewport.width = (float)mViewportWidth; + viewport.height = (float)mViewportHeight; + } + else + { + viewport.x = 0.0f; + viewport.y = 0.0f; + viewport.width = (float)SCREENWIDTH; + viewport.height = (float)SCREENHEIGHT; + } + viewport.minDepth = mViewportDepthMin; + viewport.maxDepth = mViewportDepthMax; + mCommandBuffer->setViewport(0, 1, &viewport); + mViewportChanged = false; + } + const float normScale = 1.0f / 255.0f; //glVertexAttrib4fv(VATTR_COLOR, mColor.vec); diff --git a/src/rendering/vulkan/renderer/vk_renderstate.h b/src/rendering/vulkan/renderer/vk_renderstate.h index 24ab0ab032..b2f40a7277 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.h +++ b/src/rendering/vulkan/renderer/vk_renderstate.h @@ -49,6 +49,12 @@ private: VulkanCommandBuffer *mCommandBuffer = nullptr; bool mDescriptorsChanged = true; + int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1; + int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1; + float mViewportDepthMin = 0.0f, mViewportDepthMax = 1.0f; + bool mScissorChanged = true; + bool mViewportChanged = true; + MatricesUBO mMatrices = {}; ColorsUBO mColors = {}; GlowingWallsUBO mGlowingWalls = {}; diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index bddaaacb7c..80d3e96707 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -197,6 +197,8 @@ public: void addVertexBufferBinding(int index, size_t stride); void addVertexAttribute(int location, int binding, VkFormat format, size_t offset); + void addDynamicState(VkDynamicState state); + std::unique_ptr create(VulkanDevice *device); private: @@ -211,11 +213,13 @@ private: VkPipelineColorBlendAttachmentState colorBlendAttachment = { }; VkPipelineColorBlendStateCreateInfo colorBlending = { }; VkPipelineDepthStencilStateCreateInfo depthStencil = { }; + VkPipelineDynamicStateCreateInfo dynamicState = {}; std::vector shaderStages; std::vector colorBlendAttachments; std::vector vertexInputBindings; std::vector vertexInputAttributes; + std::vector dynamicStates; }; class PipelineLayoutBuilder @@ -638,7 +642,7 @@ inline GraphicsPipelineBuilder::GraphicsPipelineBuilder() pipelineInfo.pMultisampleState = &multisampling; pipelineInfo.pDepthStencilState = nullptr; pipelineInfo.pColorBlendState = &colorBlending; - pipelineInfo.pDynamicState = nullptr; + pipelineInfo.pDynamicState = &dynamicState; pipelineInfo.subpass = 0; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipelineInfo.basePipelineIndex = -1; @@ -703,13 +707,8 @@ inline GraphicsPipelineBuilder::GraphicsPipelineBuilder() colorBlending.blendConstants[2] = 0.0f; colorBlending.blendConstants[3] = 0.0f; - /* - VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_LINE_WIDTH }; VkPipelineDynamicStateCreateInfo dynamicState = {}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicState.dynamicStateCount = 2; - dynamicState.pDynamicStates = dynamicStates; - */ } inline void GraphicsPipelineBuilder::setSubpass(int subpass) @@ -845,6 +844,13 @@ inline void GraphicsPipelineBuilder::addVertexAttribute(int location, int bindin vertexInputInfo.pVertexAttributeDescriptions = vertexInputAttributes.data(); } +inline void GraphicsPipelineBuilder::addDynamicState(VkDynamicState state) +{ + dynamicStates.push_back(state); + dynamicState.dynamicStateCount = (uint32_t)dynamicStates.size(); + dynamicState.pDynamicStates = dynamicStates.data(); +} + inline std::unique_ptr GraphicsPipelineBuilder::create(VulkanDevice *device) { VkPipeline pipeline = 0;