From 791d1089b08bd11f55bd770819d47859b9e05ed4 Mon Sep 17 00:00:00 2001 From: Aliya Pazylbekova Date: Mon, 6 Jan 2020 09:59:01 -0500 Subject: [PATCH] Add drawcall callbacks to end and next renderpass cmds For Vulkan pixel history vkCmdEndRenderPass and vkCmdNextSubpass can represent a modification, since it might be doing an implicit image resolve. Pixel history is using drawcall callbacks to figure out values pre- post- events, and vkCmdEndRenderPass and vkCmdNextSubpass might be such events. Also adds clear image usage to vkCmdBeginRenderPass(2) for images that have VK_ATTACHMENT_LOAD_OP_CLEAR. --- renderdoc/driver/vulkan/vk_counters.cpp | 33 ++++++- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 85 +++++++++++++++++++ 2 files changed, 115 insertions(+), 3 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_counters.cpp b/renderdoc/driver/vulkan/vk_counters.cpp index 5ddbed78f..c39321f41 100644 --- a/renderdoc/driver/vulkan/vk_counters.cpp +++ b/renderdoc/driver/vulkan/vk_counters.cpp @@ -399,13 +399,22 @@ struct VulkanAMDDrawCallback : public VulkanDrawcallCallback void PreDispatch(uint32_t eid, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) override { return PostDraw(eid, cmd); } void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) override { PostRedraw(eid, cmd); } - void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } + void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override + { + if(flags & DrawFlags::PassBoundary) + return; + PreDraw(eid, cmd); + } bool PostMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return false; return PostDraw(eid, cmd); } void PostRemisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return; PostRedraw(eid, cmd); } @@ -547,13 +556,22 @@ struct VulkanKHRCallback : public VulkanDrawcallCallback void PreDispatch(uint32_t eid, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) override { return PostDraw(eid, cmd); } void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) override { PostRedraw(eid, cmd); } - void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } + void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override + { + if(flags & DrawFlags::PassBoundary) + return; + PreDraw(eid, cmd); + } bool PostMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return false; return PostDraw(eid, cmd); } void PostRemisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return; PostRedraw(eid, cmd); } void AliasEvent(uint32_t primary, uint32_t alias) override @@ -740,13 +758,22 @@ struct VulkanGPUTimerCallback : public VulkanDrawcallCallback void PreDispatch(uint32_t eid, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) override { return PostDraw(eid, cmd); } void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) override { PostRedraw(eid, cmd); } - void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { PreDraw(eid, cmd); } + void PreMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override + { + if(flags & DrawFlags::PassBoundary) + return; + PreDraw(eid, cmd); + } bool PostMisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return false; return PostDraw(eid, cmd); } void PostRemisc(uint32_t eid, DrawFlags flags, VkCommandBuffer cmd) override { + if(flags & DrawFlags::PassBoundary) + return; PostRedraw(eid, cmd); } void AliasEvent(uint32_t primary, uint32_t alias) override diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 158d33f24..ba62fc50c 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -1303,8 +1303,17 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman DoPipelineBarrier(commandBuffer, imgBarriers.size(), imgBarriers.data()); } + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::BeginPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdBeginRenderPass again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), imgBarriers.data()); @@ -1349,6 +1358,22 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkComman } } + // Record image usage for images cleared in the beginning of the render pass. + const VulkanCreationInfo::RenderPass &rpinfo = + m_CreationInfo.m_RenderPass[GetResID(RenderPassBegin.renderPass)]; + const rdcarray &fbattachments = + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.fbattachments; + for(size_t i = 0; i < rpinfo.attachments.size(); i++) + { + if(rpinfo.attachments[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) + { + ResourceId image = m_CreationInfo.m_ImageView[fbattachments[i]].image; + m_BakedCmdBufferInfo[m_LastCmdBufferID].resourceUsage.push_back(make_rdcpair( + image, + EventUsage(m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID, ResourceUsage::Clear))); + } + } + rdcarray imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); @@ -1478,8 +1503,17 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass(SerialiserType &ser, VkCommandBuf if(ShouldUpdateRenderState(m_LastCmdBufferID, true)) m_RenderState.subpass++; + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::BeginPass | DrawFlags::EndPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdNextSubpass again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + rdcarray imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); @@ -1565,8 +1599,17 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandB m_Partial[Primary].renderPassActive = false; } + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::EndPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdEndRenderPass again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), imgBarriers.data()); @@ -1737,9 +1780,18 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass2(SerialiserType &ser, DoPipelineBarrier(commandBuffer, imgBarriers.size(), imgBarriers.data()); } + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::BeginPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); + ObjDisp(commandBuffer) ->CmdBeginRenderPass2(Unwrap(commandBuffer), &unwrappedInfo, &unwrappedBeginInfo); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdBeginRenderPass2 again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), imgBarriers.data()); @@ -1785,6 +1837,22 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass2(SerialiserType &ser, } } + // Record image usage for images cleared in the beginning of the render pass. + const VulkanCreationInfo::RenderPass &rpinfo = + m_CreationInfo.m_RenderPass[GetResID(RenderPassBegin.renderPass)]; + const rdcarray &fbattachments = + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.fbattachments; + for(size_t i = 0; i < rpinfo.attachments.size(); i++) + { + if(rpinfo.attachments[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) + { + ResourceId image = m_CreationInfo.m_ImageView[fbattachments[i]].image; + m_BakedCmdBufferInfo[m_LastCmdBufferID].resourceUsage.push_back(make_rdcpair( + image, + EventUsage(m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID, ResourceUsage::Clear))); + } + } + rdcarray imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); @@ -1930,9 +1998,18 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass2(SerialiserType &ser, VkCommandBu if(ShouldUpdateRenderState(m_LastCmdBufferID, true)) m_RenderState.subpass++; + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::BeginPass | DrawFlags::EndPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); + ObjDisp(commandBuffer) ->CmdNextSubpass2(Unwrap(commandBuffer), &unwrappedBeginInfo, &unwrappedEndInfo); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdNextSubpass2 again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + rdcarray imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); @@ -2039,8 +2116,16 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand m_Partial[Primary].renderPassActive = false; } + DrawFlags drawFlags = DrawFlags::PassBoundary | DrawFlags::EndPass; + uint32_t eventId = HandlePreCallback(commandBuffer, drawFlags); ObjDisp(commandBuffer)->CmdEndRenderPass2(Unwrap(commandBuffer), &unwrappedEndInfo); + if(eventId && m_DrawcallCallback->PostMisc(eventId, drawFlags, commandBuffer)) + { + // Do not call vkCmdEndRenderPass2 again. + m_DrawcallCallback->PostRemisc(eventId, drawFlags, commandBuffer); + } + ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), imgBarriers.data());