diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index 26e1eb522..c8ca219d1 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -273,10 +273,10 @@ public: // Mainly used to bind the frame-global desc set. // Can be done before binding a pipeline, so not asserting on that. void BindDescriptorSet(int setNumber, VkDescriptorSet set, VkPipelineLayout pipelineLayout) { - _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); VkRenderData data{ VKRRenderCommand::BIND_DESCRIPTOR_SET }; data.bindDescSet.setNumber = setNumber; data.bindDescSet.set = set; + data.bindDescSet.pipelineLayout = pipelineLayout; curRenderStep_->commands.push_back(data); } diff --git a/GPU/Common/ShaderUniforms.h b/GPU/Common/ShaderUniforms.h index 96cfe9841..12bc273da 100644 --- a/GPU/Common/ShaderUniforms.h +++ b/GPU/Common/ShaderUniforms.h @@ -133,12 +133,12 @@ R"( mat3x4 u_bone0; mat3x4 u_bone1; mat3x4 u_bone2; mat3x4 u_bone3; mat3x4 u_bon static const char * const ub_frame_globalstr = -R"( vec4 unused; +R"( vec4 stereoParams; )"; -// VR stuff will go here. +// Frame-global uniforms. struct UB_FrameGlobal { - float unused[4]; + float stereoParams[4]; }; void CalcCullRange(float minValues[4], float maxValues[4], bool flipViewport, bool hasNegZ); diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 71d601d80..4d933b09d 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -312,7 +312,8 @@ void DrawEngineVulkan::BeginFrame() { frame->pushVertex->Begin(vulkan); frame->pushIndex->Begin(vulkan); - // TODO: How can we make this nicer... + frame->frameDescSetUpdated = false; + tessDataTransferVulkan->SetPushBuffer(frame->pushUBO); DirtyAllUBOs(); @@ -1016,6 +1017,30 @@ void DrawEngineVulkan::DoFlush() { } void DrawEngineVulkan::UpdateUBOs(FrameData *frame) { + if (!frame->frameDescSetUpdated) { + // Push frame global constants. + UB_FrameGlobal frameConstants{}; + VkDescriptorBufferInfo frameConstantsBufInfo; + frame->pushUBO->PushUBOData(frameConstants, &frameConstantsBufInfo); + + VulkanContext *vulkan = (VulkanContext *)draw_->GetNativeObject(Draw::NativeObject::CONTEXT); + VulkanRenderManager *renderManager = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + VkDescriptorSetLayout frameDescSetLayout = (VkDescriptorSetLayout)draw_->GetNativeObject(Draw::NativeObject::FRAME_DATA_DESC_SET_LAYOUT); + + VkDescriptorSet frameDescSet = frame->descPool.Allocate(1, &frameDescSetLayout, "frame_desc_set"); + + VkWriteDescriptorSet descWrite{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + descWrite.descriptorCount = 1; + descWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descWrite.dstBinding = 0; + descWrite.dstSet = frameDescSet; + descWrite.pBufferInfo = &frameConstantsBufInfo; + vkUpdateDescriptorSets(vulkan->GetDevice(), 1, &descWrite, 0, nullptr); + renderManager->BindDescriptorSet(0, frameDescSet, pipelineLayout_); + + frame->frameDescSetUpdated = true; + } + if ((dirtyUniforms_ & DIRTY_BASE_UNIFORMS) || baseBuf == VK_NULL_HANDLE) { baseUBOOffset = shaderManager_->PushBaseBuffer(frame->pushUBO, &baseBuf); dirtyUniforms_ &= ~DIRTY_BASE_UNIFORMS; diff --git a/GPU/Vulkan/DrawEngineVulkan.h b/GPU/Vulkan/DrawEngineVulkan.h index 0cf03f275..035bc595d 100644 --- a/GPU/Vulkan/DrawEngineVulkan.h +++ b/GPU/Vulkan/DrawEngineVulkan.h @@ -255,6 +255,8 @@ private: VulkanPushBuffer *pushVertex = nullptr; VulkanPushBuffer *pushIndex = nullptr; + bool frameDescSetUpdated = false; + // We do rolling allocation and reset instead of caching across frames. That we might do later. DenseHashMap descSets;