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.
This commit is contained in:
baldurk
2015-12-30 17:58:30 +01:00
parent ee175febb8
commit 24f9f487c2
4 changed files with 92 additions and 65 deletions
+31 -23
View File
@@ -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<VulkanCreationInfo::Framebuffer::Attachment> &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<uint32_t> &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<VulkanCreationInfo::Framebuffer::Attachment> &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<uint32_t> &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
+10
View File
@@ -288,6 +288,16 @@ private:
vector<FetchAPIEvent> curEvents;
list<DrawcallTreeNode *> drawStack;
struct
{
ResourceId pipeline;
uint32_t idxWidth;
ResourceId renderPass;
ResourceId framebuffer;
uint32_t subpass;
} state;
vector< pair<ResourceId, ImageRegionState> > imgbarriers;
DrawcallTreeNode *draw; // the root draw to copy from when submitting
+35 -23
View File
@@ -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;
@@ -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<VulkanCreationInfo::RenderPass::Attachment> &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<VkCommandBuffer>(cmdid);
pipeline = GetResourceManager()->GetLiveHandle<VkPipeline>(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<VkCommandBuffer>(cmdid);
buffer = GetResourceManager()->GetLiveHandle<VkBuffer>(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);
}