From 24f9f487c24d552c68ee3851aa8e221c8d1d41f4 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 30 Dec 2015 17:58:30 +0100 Subject: [PATCH] Track state during reading on per-cmd buffer basis * The command buffer chunks can be interleaved so we can't track just using the one render state. --- renderdoc/driver/vulkan/vk_core.cpp | 54 +++++++++-------- renderdoc/driver/vulkan/vk_core.h | 10 ++++ renderdoc/driver/vulkan/vk_replay.cpp | 58 +++++++++++-------- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 35 +++++------ 4 files changed, 92 insertions(+), 65 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 15f87d148..de86803b7 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1943,38 +1943,46 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents) draw.depthOut = ResourceId(); - if(m_RenderState.framebuffer != ResourceId() && m_RenderState.renderPass != ResourceId()) + draw.indexByteWidth = 0; + draw.topology = eTopology_Unknown; + + if(m_LastCmdBufferID != ResourceId()) { - vector &atts = m_CreationInfo.m_Framebuffer[m_RenderState.framebuffer].attachments; + ResourceId pipe = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline; + if(pipe != ResourceId()) + draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, m_CreationInfo.m_Pipeline[pipe].patchControlPoints); - RDCASSERT(m_RenderState.subpass < m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size()); + draw.indexByteWidth = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth; - vector &colAtt = m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses[m_RenderState.subpass].colorAttachments; - int32_t dsAtt = m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses[m_RenderState.subpass].depthstencilAttachment; + ResourceId fb = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer; + ResourceId rp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass; + uint32_t sp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass; - RDCASSERT(colAtt.size() < 8); - - for(int i=0; i < 8 && i < colAtt.size(); i++) + if(fb != ResourceId() && rp != ResourceId()) { - RDCASSERT(colAtt[i] < atts.size()); - draw.outputs[i] = atts[ colAtt[i] ].view; - } + vector &atts = m_CreationInfo.m_Framebuffer[fb].attachments; - if(dsAtt != -1) - { - RDCASSERT(dsAtt < atts.size()); - draw.depthOut = atts[dsAtt].view; + RDCASSERT(sp < m_CreationInfo.m_RenderPass[rp].subpasses.size()); + + vector &colAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].colorAttachments; + int32_t dsAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].depthstencilAttachment; + + RDCASSERT(colAtt.size() < 8); + + for(int i=0; i < 8 && i < colAtt.size(); i++) + { + RDCASSERT(colAtt[i] < atts.size()); + draw.outputs[i] = atts[ colAtt[i] ].view; + } + + if(dsAtt != -1) + { + RDCASSERT(dsAtt < atts.size()); + draw.depthOut = atts[dsAtt].view; + } } } - ResourceId pipe = m_RenderState.graphics.pipeline; - if(pipe != ResourceId()) - draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, m_CreationInfo.m_Pipeline[pipe].patchControlPoints); - else - draw.topology = eTopology_Unknown; - - draw.indexByteWidth = m_RenderState.ibuffer.bytewidth; - if(m_LastCmdBufferID != ResourceId()) m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount++; else diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index ab811fc4a..ec6bbd11e 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -288,6 +288,16 @@ private: vector curEvents; list drawStack; + struct + { + ResourceId pipeline; + uint32_t idxWidth; + + ResourceId renderPass; + ResourceId framebuffer; + uint32_t subpass; + } state; + vector< pair > imgbarriers; DrawcallTreeNode *draw; // the root draw to copy from when submitting diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index c513f8e46..022725fa4 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2900,38 +2900,50 @@ void VulkanReplay::SavePipelineState() // Renderpass m_VulkanPipelineState.Pass.renderpass.obj = rm->GetOriginalID(state.renderPass); - m_VulkanPipelineState.Pass.renderpass.inputAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; - m_VulkanPipelineState.Pass.renderpass.colorAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; - m_VulkanPipelineState.Pass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; + if(state.renderPass != ResourceId()) + { + m_VulkanPipelineState.Pass.renderpass.inputAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; + m_VulkanPipelineState.Pass.renderpass.colorAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; + m_VulkanPipelineState.Pass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; + } m_VulkanPipelineState.Pass.framebuffer.obj = rm->GetOriginalID(state.framebuffer); - - m_VulkanPipelineState.Pass.framebuffer.width = c.m_Framebuffer[state.framebuffer].width; - m_VulkanPipelineState.Pass.framebuffer.height = c.m_Framebuffer[state.framebuffer].height; - m_VulkanPipelineState.Pass.framebuffer.layers = c.m_Framebuffer[state.framebuffer].layers; - - create_array_uninit(m_VulkanPipelineState.Pass.framebuffer.attachments, c.m_Framebuffer[state.framebuffer].attachments.size()); - for(size_t i=0; i < c.m_Framebuffer[state.framebuffer].attachments.size(); i++) + + if(state.framebuffer != ResourceId()) { - ResourceId viewid = c.m_Framebuffer[state.framebuffer].attachments[i].view; + m_VulkanPipelineState.Pass.framebuffer.width = c.m_Framebuffer[state.framebuffer].width; + m_VulkanPipelineState.Pass.framebuffer.height = c.m_Framebuffer[state.framebuffer].height; + m_VulkanPipelineState.Pass.framebuffer.layers = c.m_Framebuffer[state.framebuffer].layers; - if(viewid != ResourceId()) + create_array_uninit(m_VulkanPipelineState.Pass.framebuffer.attachments, c.m_Framebuffer[state.framebuffer].attachments.size()); + for(size_t i=0; i < c.m_Framebuffer[state.framebuffer].attachments.size(); i++) { - m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = rm->GetOriginalID(viewid); - m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = rm->GetOriginalID(c.m_ImageView[viewid].image); + ResourceId viewid = c.m_Framebuffer[state.framebuffer].attachments[i].view; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = c.m_ImageView[viewid].range.baseMipLevel; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = c.m_ImageView[viewid].range.baseArrayLayer; - } - else - { - m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = ResourceId(); - m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = ResourceId(); + if(viewid != ResourceId()) + { + m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = rm->GetOriginalID(viewid); + m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = rm->GetOriginalID(c.m_ImageView[viewid].image); - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = 0; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = 0; + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = c.m_ImageView[viewid].range.baseMipLevel; + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = c.m_ImageView[viewid].range.baseArrayLayer; + } + else + { + m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = ResourceId(); + m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = ResourceId(); + + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = 0; + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = 0; + } } } + else + { + m_VulkanPipelineState.Pass.framebuffer.width = 0; + m_VulkanPipelineState.Pass.framebuffer.height = 0; + m_VulkanPipelineState.Pass.framebuffer.layers = 0; + } m_VulkanPipelineState.Pass.renderArea.x = state.renderArea.offset.x; m_VulkanPipelineState.Pass.renderArea.y = state.renderArea.offset.y; diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 6f6483ac0..f3b74ee8a 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -28,8 +28,8 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) { string opDesc = ""; - const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_RenderState.renderPass]; - const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_RenderState.framebuffer]; + const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass]; + const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer]; const vector &atts = info.attachments; @@ -42,7 +42,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) bool colsame = true; // find which attachment is the depth-stencil one - int32_t dsAttach = info.subpasses[m_RenderState.subpass].depthstencilAttachment; + int32_t dsAttach = info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass].depthstencilAttachment; bool hasStencil = false; bool depthonly = false; @@ -51,7 +51,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) if(dsAttach >= 0) { hasStencil = !IsDepthOnlyFormat(fbinfo.attachments[dsAttach].format); - depthonly = info.subpasses[m_RenderState.subpass].colorAttachments.size() == 0; + depthonly = info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass].colorAttachments.size() == 0; } // first colour attachment, if there is one @@ -365,8 +365,8 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer( // non-baked ID. The baked ID is referenced by the submit itself. // // In vkEndCommandBuffer we erase the non-baked reference, and since - // we know the serialised command buffers are independent (ie. aren't - // overlapping in the capture even if they were recorded overlapping) + // we know you can only be recording a command buffer once at a time + // (even if it's baked to several command buffers in the frame) // there's no issue with clashes here. m_RerecordCmds[bakeId] = cmd; m_RerecordCmds[cmdId] = cmd; @@ -647,10 +647,10 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass( ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); - // track during reading - m_RenderState.subpass = 0; - m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; const string desc = localSerialiser->GetDebugStr(); @@ -734,8 +734,8 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass( ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); - // track during reading - m_RenderState.subpass++; + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++; const string desc = localSerialiser->GetDebugStr(); @@ -995,11 +995,8 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline( commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); pipeline = GetResourceManager()->GetLiveHandle(pipeid); - // track this while reading, as we need to bind current topology & index byte width to draws - if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - m_RenderState.graphics.pipeline = GetResID(pipeline); - else - m_RenderState.compute.pipeline = GetResID(pipeline); + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline = GetResID(pipeline); ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); } @@ -1331,8 +1328,8 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer( commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); buffer = GetResourceManager()->GetLiveHandle(bufid); - // track this while reading, as we need to bind current topology & index byte width to draws - m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = (idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2); ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); }