From 60f350056c55ea988bcdc459eb2f00d152e33efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 7 Apr 2024 21:43:06 +0200 Subject: [PATCH] Vulkan: Optimize away a barrier in case of no depth buffer --- Common/GPU/Vulkan/VulkanBarrier.h | 1 + Common/GPU/Vulkan/VulkanQueueRunner.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanBarrier.h b/Common/GPU/Vulkan/VulkanBarrier.h index 74a25459e5..884e0919c7 100644 --- a/Common/GPU/Vulkan/VulkanBarrier.h +++ b/Common/GPU/Vulkan/VulkanBarrier.h @@ -17,6 +17,7 @@ public: bool empty() const { return imageBarriers_.empty(); } + // TODO: Replace this with TransitionImage. VkImageMemoryBarrier *Add(VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags) { srcStageMask_ |= srcStageMask; dstStageMask_ |= dstStageMask; diff --git a/Common/GPU/Vulkan/VulkanQueueRunner.cpp b/Common/GPU/Vulkan/VulkanQueueRunner.cpp index 875e4dbbdf..f30979ee84 100644 --- a/Common/GPU/Vulkan/VulkanQueueRunner.cpp +++ b/Common/GPU/Vulkan/VulkanQueueRunner.cpp @@ -958,7 +958,6 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } // Write-after-write hazards. Fixed flicker in God of War on ARM (before we added another fix that removed these). - // These aren't so common so not bothering to combine the barrier with the pretransition one. if (step.render.framebuffer) { int n = 0; int stage = 0; @@ -976,7 +975,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT - ); + ); } if (step.render.framebuffer->depth.image != VK_NULL_HANDLE && step.render.framebuffer->depth.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { recordBarrier_.TransitionImage( @@ -995,8 +994,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c } } - // This reads the layout of the color and depth images, and chooses a render pass using them that - // will transition to the desired final layout. + // This chooses a render pass according to the load/store attachment state. We no longer transition + // image layouts as part of the passes. // // NOTE: Unconditionally flushes recordBarrier_. VKRRenderPass *renderPass = PerformBindFramebufferAsRenderTarget(step, cmd); @@ -1282,7 +1281,9 @@ VKRRenderPass *VulkanQueueRunner::PerformBindFramebufferAsRenderTarget(const VKR } recordBarrier_.TransitionColorImageAuto(&fb->color, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - if (fb->depth.image) { // } && RenderPassTypeHasDepth(step.render.renderPassType)) { + + // If the render pass doesn't touch depth, we can avoid a layout transition of the depth buffer. + if (fb->depth.image && RenderPassTypeHasDepth(step.render.renderPassType)) { recordBarrier_.TransitionDepthStencilImageAuto(&fb->depth, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); }