From 4023bf75d866fca428f145af44af14b8155bafbb Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 3 May 2018 17:10:59 +0100 Subject: [PATCH] Patch resource usage for secondary draws at execute time. Closes #975 * Once we hit vkCmdExecuteCommands we know the renderpass and framebuffer that are used with the secondary command buffer, so we can process the added draws and add resource usage to them. --- renderdoc/driver/vulkan/vk_core.cpp | 81 ++++++++++++------- renderdoc/driver/vulkan/vk_core.h | 4 + .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 20 +++++ 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 5e58c023f..2f7564adf 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -3127,43 +3127,70 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, vector= rp.subpasses.size()) { - uint32_t att = rp.subpasses[state.subpass].inputAttachments[i]; - if(att == VK_ATTACHMENT_UNUSED) - continue; - drawNode.resourceUsage.push_back( - std::make_pair(c.m_ImageView[fb.attachments[att].view].image, - EventUsage(e, ResourceUsage::InputTarget, fb.attachments[att].view))); + RDCERR("Invalid subpass index %u, only %u subpasses exist in this renderpass", subpass, + (uint32_t)rp.subpasses.size()); } - - for(size_t i = 0; i < rp.subpasses[state.subpass].colorAttachments.size(); i++) + else { - uint32_t att = rp.subpasses[state.subpass].colorAttachments[i]; - if(att == VK_ATTACHMENT_UNUSED) - continue; - drawNode.resourceUsage.push_back( - std::make_pair(c.m_ImageView[fb.attachments[att].view].image, - EventUsage(e, ResourceUsage::ColorTarget, fb.attachments[att].view))); - } + const VulkanCreationInfo::RenderPass::Subpass &sub = rp.subpasses[subpass]; - if(rp.subpasses[state.subpass].depthstencilAttachment >= 0) - { - int32_t att = rp.subpasses[state.subpass].depthstencilAttachment; - drawNode.resourceUsage.push_back(std::make_pair( - c.m_ImageView[fb.attachments[att].view].image, - EventUsage(e, ResourceUsage::DepthStencilTarget, fb.attachments[att].view))); + for(size_t i = 0; i < sub.inputAttachments.size(); i++) + { + uint32_t att = sub.inputAttachments[i]; + if(att == VK_ATTACHMENT_UNUSED) + continue; + drawNode.resourceUsage.push_back( + std::make_pair(c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, ResourceUsage::InputTarget, fb.attachments[att].view))); + } + + for(size_t i = 0; i < sub.colorAttachments.size(); i++) + { + uint32_t att = sub.colorAttachments[i]; + if(att == VK_ATTACHMENT_UNUSED) + continue; + drawNode.resourceUsage.push_back( + std::make_pair(c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, ResourceUsage::ColorTarget, fb.attachments[att].view))); + } + + if(sub.depthstencilAttachment >= 0) + { + int32_t att = sub.depthstencilAttachment; + drawNode.resourceUsage.push_back(std::make_pair( + c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, ResourceUsage::DepthStencilTarget, fb.attachments[att].view))); + } } } } +void WrappedVulkan::AddFramebufferUsageAllChildren(VulkanDrawcallTreeNode &drawNode, + ResourceId renderPass, ResourceId framebuffer, + uint32_t subpass) +{ + for(VulkanDrawcallTreeNode &c : drawNode.children) + AddFramebufferUsageAllChildren(c, renderPass, framebuffer, subpass); + + AddFramebufferUsage(drawNode, renderPass, framebuffer, subpass); +} + void WrappedVulkan::AddEvent() { APIEvent apievent; diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index f8258fb1f..3882bb8b0 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -735,6 +735,10 @@ private: void AddEvent(); void AddUsage(VulkanDrawcallTreeNode &drawNode, vector &debugMessages); + void AddFramebufferUsage(VulkanDrawcallTreeNode &drawNode, ResourceId renderPass, + ResourceId framebuffer, uint32_t subpass); + void AddFramebufferUsageAllChildren(VulkanDrawcallTreeNode &drawNode, ResourceId renderPass, + ResourceId framebuffer, uint32_t subpass); // no copy semantics WrappedVulkan(const WrappedVulkan &); diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 197797a7c..06608d2a2 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -2515,6 +2515,10 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkComman parentCmdBufInfo.curEventID++; + // should we add framebuffer usage to the child draws. + bool framebufferUsage = parentCmdBufInfo.state.renderPass != ResourceId() && + parentCmdBufInfo.state.framebuffer != ResourceId(); + for(uint32_t c = 0; c < commandBufferCount; c++) { ResourceId cmd = GetResourceManager()->GetOriginalID(GetResID(pCommandBuffers[c])); @@ -2543,6 +2547,22 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkComman parentCmdBufInfo.draw->InsertAndUpdateIDs(*cmdBufInfo.draw, parentCmdBufInfo.curEventID, parentCmdBufInfo.drawCount); + if(framebufferUsage) + { + size_t total = parentCmdBufInfo.draw->children.size(); + size_t numChildren = cmdBufInfo.draw->children.size(); + + // iterate through the newly added draws, and recursively add usage to them using our + // primary command buffer's state + for(size_t i = 0; i < numChildren; i++) + { + AddFramebufferUsageAllChildren(parentCmdBufInfo.draw->children[total - numChildren + i], + parentCmdBufInfo.state.renderPass, + parentCmdBufInfo.state.framebuffer, + parentCmdBufInfo.state.subpass); + } + } + for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++) { parentCmdBufInfo.debugMessages.push_back(cmdBufInfo.debugMessages[i]);