From 19f4133768bd69ee1277a58031de133c6bd05fbd Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 26 Feb 2019 16:50:54 +0100 Subject: [PATCH] - move most push constants to dynamic uniform buffers --- .../vulkan/renderer/vk_renderpass.cpp | 8 +++- .../vulkan/renderer/vk_renderstate.cpp | 12 +++--- .../vulkan/renderer/vk_renderstate.h | 7 +++- src/rendering/vulkan/shaders/vk_shader.cpp | 41 ++++++++++--------- src/rendering/vulkan/shaders/vk_shader.h | 22 ++++++---- .../vulkan/system/vk_framebuffer.cpp | 8 ++++ src/rendering/vulkan/system/vk_framebuffer.h | 3 ++ 7 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/rendering/vulkan/renderer/vk_renderpass.cpp b/src/rendering/vulkan/renderer/vk_renderpass.cpp index 320b43fe3b..091cd06e5c 100644 --- a/src/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/rendering/vulkan/renderer/vk_renderpass.cpp @@ -58,6 +58,9 @@ void VkRenderPassManager::CreateDynamicSetLayout() DescriptorSetLayoutBuilder builder; builder.addBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); builder.addBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + builder.addBinding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + builder.addBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); + builder.addBinding(4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); DynamicSetLayout = builder.create(GetVulkanFrameBuffer()->device); } @@ -87,7 +90,7 @@ void VkRenderPassManager::CreatePipelineLayout() void VkRenderPassManager::CreateDescriptorPool() { DescriptorPoolBuilder builder; - builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1); + builder.addPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 4); builder.addPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1); builder.addPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 512 * 6); builder.setMaxSets(512); @@ -102,6 +105,9 @@ void VkRenderPassManager::CreateDynamicSet() WriteDescriptors update; update.addBuffer(DynamicSet.get(), 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ViewpointUBO->mBuffer.get(), 0, sizeof(HWViewpointUniforms)); update.addBuffer(DynamicSet.get(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, fb->LightBufferSSO->mBuffer.get(), 0, 4096); + update.addBuffer(DynamicSet.get(), 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->MatricesUBO->mBuffer.get(), 0, sizeof(MatricesUBO)); + update.addBuffer(DynamicSet.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->ColorsUBO->mBuffer.get(), 0, sizeof(ColorsUBO)); + update.addBuffer(DynamicSet.get(), 4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, fb->GlowingWallsUBO->mBuffer.get(), 0, sizeof(GlowingWallsUBO)); update.updateSets(fb->device); } diff --git a/src/rendering/vulkan/renderer/vk_renderstate.cpp b/src/rendering/vulkan/renderer/vk_renderstate.cpp index 3701fe3511..584ec4c3e9 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.cpp +++ b/src/rendering/vulkan/renderer/vk_renderstate.cpp @@ -42,7 +42,7 @@ void VkRenderState::Draw(int dt, int index, int count, bool apply) BindDescriptorSets(); drawcalls.Clock(); - //mCommandBuffer->draw(count, 1, index, 0); + mCommandBuffer->draw(count, 1, index, 0); drawcalls.Unclock(); } @@ -54,7 +54,7 @@ void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply) BindDescriptorSets(); drawcalls.Clock(); - //mCommandBuffer->drawIndexed(count, 1, 0, index * (int)sizeof(uint32_t), 0); + mCommandBuffer->drawIndexed(count, 1, 0, index * (int)sizeof(uint32_t), 0); drawcalls.Unclock(); } @@ -155,9 +155,7 @@ void VkRenderState::Apply(int dt) mCommandBuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); } - // To do: maybe only push the subset that changed? - static_assert(sizeof(PushConstants) % 16 == 0, "std140 layouts must be 16 byte aligned"); - //mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants); + mCommandBuffer->pushConstants(passManager->PipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &mPushConstants); VkBuffer vertexBuffers[] = { static_cast(mVertexBuffer)->mBuffer->buffer }; VkDeviceSize offsets[] = { 0 }; @@ -196,8 +194,8 @@ void VkRenderState::BindDescriptorSets() auto fb = GetVulkanFrameBuffer(); auto passManager = fb->GetRenderPassManager(); - uint32_t offsets[2] = { mViewpointOffset, mLightBufferOffset }; - mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 2, offsets); + uint32_t offsets[5] = { mViewpointOffset, mLightBufferOffset, mMatricesOffset, mColorsOffset, mGlowingWallsOffset }; + mCommandBuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passManager->PipelineLayout.get(), 0, passManager->DynamicSet.get(), 5, offsets); mDescriptorsChanged = false; } diff --git a/src/rendering/vulkan/renderer/vk_renderstate.h b/src/rendering/vulkan/renderer/vk_renderstate.h index 982b6d63aa..48def555a7 100644 --- a/src/rendering/vulkan/renderer/vk_renderstate.h +++ b/src/rendering/vulkan/renderer/vk_renderstate.h @@ -50,6 +50,9 @@ private: PushConstants mPushConstants; bool mDescriptorsChanged = true; - uint32_t mViewpointOffset = 0, mLastViewpointOffset = 0; - uint32_t mLightBufferOffset = 0, mLastLightBufferOffset = 0; + uint32_t mViewpointOffset = 0; + uint32_t mLightBufferOffset = 0; + uint32_t mMatricesOffset = 0; + uint32_t mColorsOffset = 0; + uint32_t mGlowingWallsOffset = 0; }; diff --git a/src/rendering/vulkan/shaders/vk_shader.cpp b/src/rendering/vulkan/shaders/vk_shader.cpp index 34fad3e6d0..ce4568ec6d 100644 --- a/src/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/rendering/vulkan/shaders/vk_shader.cpp @@ -46,28 +46,13 @@ static const char *shaderBindings = R"( vec4 lights[]; }; - // textures - layout(set = 1, binding = 0) uniform sampler2D tex; - // layout(set = 1, binding = 1) uniform sampler2D texture2; - // layout(set = 1, binding = 2) uniform sampler2D texture3; - // layout(set = 1, binding = 3) uniform sampler2D texture4; - // layout(set = 1, binding = 4) uniform sampler2D texture5; - // layout(set = 1, binding = 5) uniform sampler2D texture6; - // layout(set = 1, binding = 16) uniform sampler2D ShadowMap; - - // This must match the PushConstants struct - layout(push_constant, std140) uniform PushConstants - { - // matrices + layout(set = 0, binding = 2, std140) uniform MatricesUBO { mat4 ModelMatrix; mat4 NormalModelMatrix; mat4 TextureMatrix; + }; - int uTextureMode; - float uAlphaThreshold; - vec2 uClipSplit; - - // colors + layout(set = 0, binding = 3, std140) uniform ColorsUBO { vec4 uObjectColor; vec4 uObjectColor2; vec4 uDynLightColor; @@ -76,8 +61,9 @@ static const char *shaderBindings = R"( float uDesaturationFactor; float uInterpolationFactor; float padding0, padding1; + }; - // Glowing walls stuff + layout(set = 0, binding = 4, std140) uniform GlowingWallsUBO { vec4 uGlowTopPlane; vec4 uGlowTopColor; vec4 uGlowBottomPlane; @@ -88,6 +74,23 @@ static const char *shaderBindings = R"( vec4 uSplitTopPlane; vec4 uSplitBottomPlane; + }; + + // textures + layout(set = 1, binding = 0) uniform sampler2D tex; + // layout(set = 1, binding = 1) uniform sampler2D texture2; + // layout(set = 1, binding = 2) uniform sampler2D texture3; + // layout(set = 1, binding = 3) uniform sampler2D texture4; + // layout(set = 1, binding = 4) uniform sampler2D texture5; + // layout(set = 1, binding = 5) uniform sampler2D texture6; + // layout(set = 1, binding = 16) uniform sampler2D ShadowMap; + + // This must match the PushConstants struct + layout(push_constant) uniform PushConstants + { + int uTextureMode; + float uAlphaThreshold; + vec2 uClipSplit; // Lighting + Fog float uLightLevel; diff --git a/src/rendering/vulkan/shaders/vk_shader.h b/src/rendering/vulkan/shaders/vk_shader.h index 89877aab0c..c535dc7739 100644 --- a/src/rendering/vulkan/shaders/vk_shader.h +++ b/src/rendering/vulkan/shaders/vk_shader.h @@ -8,18 +8,15 @@ class VulkanDevice; class VulkanShader; -struct PushConstants +struct MatricesUBO { - // matrices VSMatrix ModelMatrix; VSMatrix NormalModelMatrix; VSMatrix TextureMatrix; +}; - int uTextureMode; - float uAlphaThreshold; - FVector2 uClipSplit; - - // colors +struct ColorsUBO +{ FVector4 uObjectColor; FVector4 uObjectColor2; FVector4 uDynLightColor; @@ -28,8 +25,10 @@ struct PushConstants float uDesaturationFactor; float uInterpolationFactor; float padding0, padding1; +}; - // Glowing walls stuff +struct GlowingWallsUBO +{ FVector4 uGlowTopPlane; FVector4 uGlowTopColor; FVector4 uGlowBottomPlane; @@ -40,6 +39,13 @@ struct PushConstants FVector4 uSplitTopPlane; FVector4 uSplitBottomPlane; +}; + +struct PushConstants +{ + int uTextureMode; + float uAlphaThreshold; + FVector2 uClipSplit; // Lighting + Fog float uLightLevel; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index 2d30161be1..5d186ced4c 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -77,6 +77,14 @@ void VulkanFrameBuffer::InitializeState() mViewpoints = new GLViewpointBuffer; mLights = new FLightBuffer(); + // To do: move this to HW renderer interface maybe? + MatricesUBO = (VKDataBuffer*)CreateDataBuffer(1234, false); + ColorsUBO = (VKDataBuffer*)CreateDataBuffer(1234, false); + GlowingWallsUBO = (VKDataBuffer*)CreateDataBuffer(1234, false); + MatricesUBO->SetData(sizeof(MatricesUBO) * 128, 0, false); + ColorsUBO->SetData(sizeof(ColorsUBO) * 128, 0, false); + GlowingWallsUBO->SetData(sizeof(GlowingWallsUBO) * 128, 0, false); + mShaderManager.reset(new VkShaderManager(device)); mSamplerManager.reset(new VkSamplerManager(device)); mRenderPassManager.reset(new VkRenderPassManager()); diff --git a/src/rendering/vulkan/system/vk_framebuffer.h b/src/rendering/vulkan/system/vk_framebuffer.h index 4e2d9d05e2..ff0187d5a6 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.h +++ b/src/rendering/vulkan/system/vk_framebuffer.h @@ -28,6 +28,9 @@ public: VKDataBuffer *ViewpointUBO = nullptr; VKDataBuffer *LightBufferSSO = nullptr; + VKDataBuffer *MatricesUBO = nullptr; + VKDataBuffer *ColorsUBO = nullptr; + VKDataBuffer *GlowingWallsUBO = nullptr; VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev); ~VulkanFrameBuffer();