mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-19 00:11:02 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user