From feb20a298fe3dd57fdff5ea0368ae2fbcdc98298 Mon Sep 17 00:00:00 2001 From: Greg Fischer Date: Tue, 1 Dec 2015 18:20:48 -0700 Subject: [PATCH] execute barriers for all subresources of an image --- renderdoc/driver/vulkan/vk_initstate.cpp | 42 ++++++++++------- renderdoc/driver/vulkan/vk_replay.cpp | 57 +++++++++++++++--------- 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 91bb62c58..8019c1fc7 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -1697,11 +1697,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERT(vkr == VK_SUCCESS); - // VKTODOMED handle multiple subresources with different layouts etc VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, 0, 0, - m_ImageLayouts[id].subresourceStates[0].newLayout, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, ToHandle(live), { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }, @@ -1716,16 +1715,19 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager // clear completes before subsequent operations barrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT; - void *barrierptr = (void *)&barrier; - - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + void *barrierptr = (void *)&barrier; + + for (int si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + } VkClearColorValue clearval = { 0.0f, 0.0f, 0.0f, 0.0f }; VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToHandle(live), VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, &clearval, 1, &range); - barrier.newLayout = barrier.oldLayout; barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL; // complete clear before any other work @@ -1740,8 +1742,12 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT| VK_MEMORY_INPUT_INPUT_ATTACHMENT_BIT| VK_MEMORY_INPUT_TRANSFER_BIT; - - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + + for (int si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + } vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERT(vkr == VK_SUCCESS); @@ -1753,11 +1759,10 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERT(vkr == VK_SUCCESS); - // VKTODOMED handle multiple subresources with different layouts etc VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, 0, 0, - m_ImageLayouts[id].subresourceStates[0].newLayout, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, ToHandle(live), { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }, @@ -1773,15 +1778,18 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager barrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT; void *barrierptr = (void *)&barrier; - - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + + for (int si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + } VkClearDepthStencilValue clearval = { 1.0f, 0 }; VkImageSubresourceRange range = { VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; ObjDisp(cmd)->CmdClearDepthStencilImage(Unwrap(cmd), ToHandle(live), VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, &clearval, 1, &range); - barrier.newLayout = barrier.oldLayout; barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL; // complete clear before any other work @@ -1796,8 +1804,12 @@ void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT| VK_MEMORY_INPUT_INPUT_ATTACHMENT_BIT| VK_MEMORY_INPUT_TRANSFER_BIT; - - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + + for (int si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrierptr); + } vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); RDCASSERT(vkr == VK_SUCCESS); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 9ce39359f..46cfe8149 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -946,9 +946,6 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn ImageLayouts &layouts = m_pDriver->m_ImageLayouts[cfg.texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[cfg.texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.texid); - - // VKTODOMED handle multiple subresources with different layouts etc - VkImageLayout origLayout = layouts.subresourceStates[0].newLayout; VkImageView liveImView = iminfo.view; bool isDepth = (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; @@ -1102,7 +1099,7 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn VkImageMemoryBarrier srcimBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, origLayout, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), { VkImageAspectFlags(isDepth ? (VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_COLOR_BIT), 0, 1, 0, 1 } @@ -1123,7 +1120,12 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn void *barrier = (void *)&srcimBarrier; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } + srcimBarrier.oldLayout = srcimBarrier.newLayout; srcimBarrier.outputMask = 0; @@ -1148,8 +1150,11 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn vt->CmdEndRenderPass(Unwrap(cmd)); } - srcimBarrier.newLayout = origLayout; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } vt->EndCommandBuffer(Unwrap(cmd)); @@ -3292,9 +3297,6 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - - // VKTODOMED handle multiple subresources with different layouts etc - VkImageLayout origLayout = layouts.subresourceStates[0].newLayout; VkImageView liveImView = iminfo.view; if(liveImView == VK_NULL_HANDLE) @@ -3400,7 +3402,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, VkImageMemoryBarrier srcimBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, origLayout, VK_IMAGE_LAYOUT_GENERAL, + 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } @@ -3421,7 +3423,12 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, void *barrier = (void *)&srcimBarrier; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } + srcimBarrier.oldLayout = srcimBarrier.newLayout; srcimBarrier.outputMask = 0; @@ -3445,8 +3452,11 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, }; // image layout back to normal - srcimBarrier.newLayout = origLayout; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } // ensure shader writes complete before coalescing the tiles barrier = (void *)&tilebarrier; @@ -3513,9 +3523,6 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - - // VKTODOMED handle multiple subresources with different layouts etc - VkImageLayout origLayout = layouts.subresourceStates[0].newLayout; VkImageView liveImView = iminfo.view; if(liveImView == VK_NULL_HANDLE) @@ -3610,7 +3617,7 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m VkImageMemoryBarrier srcimBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, origLayout, VK_IMAGE_LAYOUT_GENERAL, + 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, Unwrap(liveIm), { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } @@ -3631,7 +3638,12 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m void *barrier = (void *)&srcimBarrier; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } + srcimBarrier.oldLayout = srcimBarrier.newLayout; srcimBarrier.outputMask = 0; @@ -3657,8 +3669,11 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m }; // image layout back to normal - srcimBarrier.newLayout = origLayout; - vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + for (int si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + vt->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier); + } // ensure shader writes complete before copying to readback buf barrier = (void *)&tilebarrier;