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.
This commit is contained in:
baldurk
2018-05-03 17:10:59 +01:00
parent e65bc4506e
commit 4023bf75d8
3 changed files with 78 additions and 27 deletions
+54 -27
View File
@@ -3127,43 +3127,70 @@ void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, vector<DebugMessa
//////////////////////////////
// Framebuffer/renderpass
if(state.renderPass != ResourceId() && state.framebuffer != ResourceId())
AddFramebufferUsage(drawNode, state.renderPass, state.framebuffer, state.subpass);
}
void WrappedVulkan::AddFramebufferUsage(VulkanDrawcallTreeNode &drawNode, ResourceId renderPass,
ResourceId framebuffer, uint32_t subpass)
{
VulkanCreationInfo &c = m_CreationInfo;
uint32_t e = drawNode.draw.eventId;
if(renderPass != ResourceId() && framebuffer != ResourceId())
{
VulkanCreationInfo::RenderPass &rp = c.m_RenderPass[state.renderPass];
VulkanCreationInfo::Framebuffer &fb = c.m_Framebuffer[state.framebuffer];
const VulkanCreationInfo::RenderPass &rp = c.m_RenderPass[renderPass];
const VulkanCreationInfo::Framebuffer &fb = c.m_Framebuffer[framebuffer];
RDCASSERT(state.subpass < rp.subpasses.size());
for(size_t i = 0; i < rp.subpasses[state.subpass].inputAttachments.size(); i++)
if(subpass >= 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;
+4
View File
@@ -735,6 +735,10 @@ private:
void AddEvent();
void AddUsage(VulkanDrawcallTreeNode &drawNode, vector<DebugMessage> &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 &);
@@ -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]);