Don't forcibly disjoint all cmd buffers and sort to the start

* I misunderstood how descriptor sets were used - they are allowed to be
  dereferenced anywhere between cmd buffer record time and when
  execution finishes. I thought they were only ever dereferenced during
  exec. So it means we must preserve cmd buffer ordering vs. queue
  submit and descriptor update. We still want to force cmd buffers into
  the start of the frame that were recorded pre-frame though.
This commit is contained in:
baldurk
2016-02-07 18:40:57 +01:00
parent c76466626c
commit 5525a767a6
6 changed files with 218 additions and 124 deletions
+55 -83
View File
@@ -296,12 +296,12 @@ WrappedVulkan::WrappedVulkan(const char *logFilename)
m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0;
m_CurEventID = 1;
m_CurDrawcallID = 1;
m_RootEventID = 1;
m_RootDrawcallID = 1;
m_FirstEventID = 0;
m_LastEventID = ~0U;
m_CurCmdBufferID = ResourceId();
m_LastCmdBufferID = ResourceId();
m_PartialReplayData.renderPassActive = false;
m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE;
@@ -680,12 +680,14 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
m_pSerialiser->PopContext(NULL, header);
m_CurEvents.clear();
m_RootEvents.clear();
m_CmdBuffersInProgress = 0;
if(m_State == EXECUTING)
{
FetchAPIEvent ev = GetEvent(startEventID);
m_CurEventID = ev.eventID;
m_RootEventID = ev.eventID;
// if not partial, we need to be sure to replay
// past the command buffer records, so can't
@@ -704,8 +706,8 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
}
else if(m_State == READING)
{
m_CurEventID = 1;
m_CurDrawcallID = 1;
m_RootEventID = 1;
m_RootDrawcallID = 1;
m_FirstEventID = 0;
m_LastEventID = ~0U;
}
@@ -717,7 +719,7 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
while(1)
{
if(m_State == EXECUTING && m_CurEventID > endEventID && m_CurCmdBufferID == ResourceId())
if(m_State == EXECUTING && m_RootEventID > endEventID && m_CmdBuffersInProgress == 0)
{
// we can just break out if we've done all the events desired.
// note that the command buffer events aren't 'real' and we just blaze through them
@@ -728,6 +730,8 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
VulkanChunkType context = (VulkanChunkType)m_pSerialiser->PushContext(NULL, 1, false);
m_LastCmdBufferID = ResourceId();
ContextProcessChunk(offset, context, false);
RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize()));
@@ -736,8 +740,11 @@ void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, u
// but for now this will do.
if(context == CONTEXT_CAPTURE_FOOTER)
break;
m_CurEventID++;
if(m_LastCmdBufferID != ResourceId())
m_CmdBufferInfo[m_LastCmdBufferID].curEventID++;
else
m_RootEventID++;
}
if(m_State == READING)
@@ -774,14 +781,10 @@ void WrappedVulkan::ContextProcessChunk(uint64_t offset, VulkanChunkType chunk,
uint64_t cOffs = m_pSerialiser->GetOffset();
WrappedVulkan *context = this;
LogState state = context->m_State;
LogState state = m_State;
if(forceExecute)
context->m_State = EXECUTING;
else
context->m_State = m_State;
m_State = EXECUTING;
m_AddedDrawcall = false;
@@ -789,76 +792,36 @@ void WrappedVulkan::ContextProcessChunk(uint64_t offset, VulkanChunkType chunk,
m_pSerialiser->PopContext(NULL, chunk);
if(context->m_State == READING && chunk == SET_MARKER)
if(m_State == READING && chunk == SET_MARKER)
{
// no push/pop necessary
}
else if(context->m_State == READING && chunk == BEGIN_EVENT)
else if(m_State == READING && chunk == BEGIN_EVENT)
{
// push down the drawcallstack to the latest drawcall
context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back());
GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back());
}
else if(context->m_State == READING && chunk == END_EVENT)
else if(m_State == READING && chunk == END_EVENT)
{
// refuse to pop off further than the root drawcall (mismatched begin/end events e.g.)
RDCASSERT(context->m_DrawcallStack.size() > 1);
if(context->m_DrawcallStack.size() > 1)
context->m_DrawcallStack.pop_back();
RDCASSERT(GetDrawcallStack().size() > 1);
if(GetDrawcallStack().size() > 1)
GetDrawcallStack().pop_back();
}
else if(chunk == BEGIN_CMD_BUFFER)
else if(m_State == READING && (chunk == BEGIN_CMD_BUFFER || chunk == END_CMD_BUFFER))
{
if(context->m_State == READING)
{
DrawcallTreeNode *draw = new DrawcallTreeNode;
RDCASSERT(m_CurCmdBufferID != ResourceId());
m_CmdBufferInfo[m_CurCmdBufferID].draw = draw;
context->m_DrawcallStack.push_back(draw);
}
// we know that command buffers always come before any other events,
// so we aren't trashing useful data here.
// We restart the count from 1 to account for a fake marker at the
// start of the command buffer, but the events and drawcalls recorded
// locally into the command buffers drawcall in m_CmdBufferInfo are
// 0-based. Then on queue submit we just increment all child
// events/drawcalls by the current 'next' ID and insert them into
// the tree.
// this happens on reading AND executing to make sure event IDs stay
// consistent
m_CurEventID = 1;
m_CurDrawcallID = 1;
// don't add these events - they will be handled when inserted in-line into queue submit
}
else if(chunk == END_CMD_BUFFER)
{
if(context->m_State == READING)
{
RDCASSERT(m_CurCmdBufferID != ResourceId());
m_CmdBufferInfo[m_CurCmdBufferID].eventCount = m_CurEventID;
m_CmdBufferInfo[m_CurCmdBufferID].drawCount = m_CurDrawcallID;
if(context->m_DrawcallStack.size() > 1)
context->m_DrawcallStack.pop_back();
}
m_CurCmdBufferID = ResourceId();
// reset to starting event/drawcall IDs as we might be doing the actual
// frame events now
m_CurEventID = 1;
m_CurDrawcallID = 1;
}
else if(context->m_State == READING)
else if(m_State == READING)
{
if(!m_AddedDrawcall)
context->AddEvent(chunk, m_pSerialiser->GetDebugStr());
AddEvent(chunk, m_pSerialiser->GetDebugStr());
}
m_AddedDrawcall = false;
if(forceExecute)
context->m_State = state;
m_State = state;
}
void WrappedVulkan::ProcessChunk(uint64_t offset, VulkanChunkType context)
@@ -1279,11 +1242,9 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents)
{
m_AddedDrawcall = true;
WrappedVulkan *context = this;
FetchDrawcall draw = d;
draw.eventID = m_CurEventID;
draw.drawcallID = m_CurDrawcallID;
draw.eventID = m_LastCmdBufferID != ResourceId() ? m_CmdBufferInfo[m_LastCmdBufferID].curEventID : m_RootEventID;
draw.drawcallID = m_LastCmdBufferID != ResourceId() ? m_CmdBufferInfo[m_LastCmdBufferID].drawCount : m_RootDrawcallID;
for(int i=0; i < 8; i++)
draw.outputs[i] = ResourceId();
@@ -1298,17 +1259,25 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents)
draw.indexByteWidth = m_PartialReplayData.state.ibuffer.bytewidth;
m_CurDrawcallID++;
if(m_LastCmdBufferID != ResourceId())
m_CmdBufferInfo[m_LastCmdBufferID].drawCount++;
else
m_RootDrawcallID++;
if(hasEvents)
{
vector<FetchAPIEvent> &srcEvents = m_LastCmdBufferID != ResourceId() ? m_CmdBufferInfo[m_LastCmdBufferID].curEvents : m_RootEvents;
// VKTODOLOW the whole 'context' filter thing will go away so this will be
// a straight copy
vector<FetchAPIEvent> evs;
evs.reserve(m_CurEvents.size());
for(size_t i=0; i < m_CurEvents.size(); )
evs.reserve(srcEvents.size());
for(size_t i=0; i < srcEvents.size(); )
{
if(m_CurEvents[i].context == draw.context)
if(srcEvents[i].context == draw.context)
{
evs.push_back(m_CurEvents[i]);
m_CurEvents.erase(m_CurEvents.begin()+i);
evs.push_back(srcEvents[i]);
srcEvents.erase(srcEvents.begin()+i);
}
else
{
@@ -1323,11 +1292,11 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents)
// should have at least the root drawcall here, push this drawcall
// onto the back's children list.
if(!context->m_DrawcallStack.empty())
if(!GetDrawcallStack().empty())
{
DrawcallTreeNode node(draw);
node.children.insert(node.children.begin(), draw.children.elems, draw.children.elems+draw.children.count);
context->m_DrawcallStack.back()->children.push_back(node);
GetDrawcallStack().back()->children.push_back(node);
}
else
RDCERR("Somehow lost drawcall stack!");
@@ -1339,7 +1308,7 @@ void WrappedVulkan::AddEvent(VulkanChunkType type, string description)
apievent.context = ResourceId();
apievent.fileOffset = m_CurChunkOffset;
apievent.eventID = m_CurEventID;
apievent.eventID = m_LastCmdBufferID != ResourceId() ? m_CmdBufferInfo[m_LastCmdBufferID].eventCount : m_RootEventID;
apievent.eventDesc = description;
@@ -1350,9 +1319,12 @@ void WrappedVulkan::AddEvent(VulkanChunkType type, string description)
memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t)*stack->NumLevels());
}
m_CurEvents.push_back(apievent);
if(m_LastCmdBufferID != ResourceId())
m_CmdBufferInfo[m_LastCmdBufferID].curEvents.push_back(apievent);
else
m_RootEvents.push_back(apievent);
if(m_State == READING && m_CurCmdBufferID == ResourceId())
if(m_State == READING && m_CmdBuffersInProgress == 0)
m_Events.push_back(apievent);
}
+19 -7
View File
@@ -191,16 +191,20 @@ private:
vector< pair<ResourceId, ImageRegionState> > imgtransitions;
// used on replay
vector<FetchAPIEvent> curEvents;
list<DrawcallTreeNode *> drawStack;
DrawcallTreeNode *draw; // the root draw to copy from when submitting
uint32_t eventCount; // how many events are in this cmd buffer, for quick skipping
uint32_t curEventID; // current event ID while reading or executing
uint32_t drawCount; // similar to above
};
map<ResourceId, CmdBufferInfo> m_CmdBufferInfo;
// on replay, the current command buffer we're handling (we know
// that these don't overlap as that disjoint ordering is guaranteed
// on capture).
ResourceId m_CurCmdBufferID;
// on replay, the current command buffer for the last chunk we
// handled.
ResourceId m_LastCmdBufferID;
int m_CmdBuffersInProgress;
struct PartialReplayData
{
@@ -299,7 +303,7 @@ private:
} m_PartialReplayData;
bool IsPartialCmd(ResourceId cmdid) { return cmdid == m_PartialReplayData.partialParent; }
bool InPartialRange() { return m_CurEventID <= m_LastEventID - m_PartialReplayData.baseEvent; }
bool InPartialRange() { return m_CmdBufferInfo[m_PartialReplayData.partialParent].curEventID <= m_LastEventID - m_PartialReplayData.baseEvent; }
VkCmdBuffer PartialCmdBuf() { return m_PartialReplayData.resultPartialCmdBuffer; }
struct SwapInfo
@@ -350,11 +354,11 @@ private:
// replay
vector<FetchAPIEvent> m_CurEvents, m_Events;
vector<FetchAPIEvent> m_RootEvents, m_Events;
bool m_AddedDrawcall;
uint64_t m_CurChunkOffset;
uint32_t m_CurEventID, m_CurDrawcallID;
uint32_t m_RootEventID, m_RootDrawcallID;
uint32_t m_FirstEventID, m_LastEventID;
DrawcallTreeNode m_ParentDrawcall;
@@ -362,6 +366,14 @@ private:
void RefreshIDs(vector<DrawcallTreeNode> &nodes, uint32_t baseEventID, uint32_t baseDrawID);
list<DrawcallTreeNode *> m_DrawcallStack;
list<DrawcallTreeNode *> &GetDrawcallStack()
{
if(m_LastCmdBufferID != ResourceId())
return m_CmdBufferInfo[m_LastCmdBufferID].drawStack;
return m_DrawcallStack;
}
void ProcessChunk(uint64_t offset, VulkanChunkType context);
void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial);
@@ -165,9 +165,11 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(
device = m_CmdBufferInfo[cmdId].device;
createInfo = m_CmdBufferInfo[cmdId].createInfo;
}
else
if(m_State < WRITING)
{
m_CurCmdBufferID = bakeId;
m_LastCmdBufferID = cmdId;
m_CmdBuffersInProgress++;
}
SERIALISE_ELEMENT(ResourceId, devId, GetResID(device));
@@ -212,6 +214,8 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(
ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &info);
}
}
m_CmdBufferInfo[cmdId].curEventID = 0;
}
else if(m_State == READING)
{
@@ -244,8 +248,16 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(
}
{
ResourceId liveBaked = GetResourceManager()->GetLiveID(bakeId);
m_CmdBufferInfo[liveBaked].device = VK_NULL_HANDLE;
DrawcallTreeNode *draw = new DrawcallTreeNode;
m_CmdBufferInfo[cmdId].draw = draw;
// On queue submit we increment all child events/drawcalls by
// m_CurEventID insert them into the tree.
m_CmdBufferInfo[cmdId].curEventID = 0;
m_CmdBufferInfo[cmdId].eventCount = 0;
m_CmdBufferInfo[cmdId].drawCount = 0;
m_CmdBufferInfo[cmdId].drawStack.push_back(draw);
}
ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &info);
@@ -299,6 +311,12 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId);
if(m_State < WRITING)
{
m_LastCmdBufferID = cmdId;
m_CmdBuffersInProgress--;
}
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdId))
@@ -314,7 +332,7 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
m_PartialReplayData.partialParent = ResourceId();
}
m_CurEventID--;
m_CmdBufferInfo[cmdId].curEventID = 0;
}
else if(m_State == READING)
{
@@ -324,7 +342,7 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
ObjDisp(cmdBuffer)->EndCommandBuffer(Unwrap(cmdBuffer));
if(!m_CurEvents.empty())
if(!m_CmdBufferInfo[m_LastCmdBufferID].curEvents.empty())
{
FetchDrawcall draw;
draw.name = "API Calls";
@@ -332,10 +350,27 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(VkCmdBuffer cmdBuffer)
// the outer loop will increment the event ID but we've not
// actually added anything just wrapped up the existing EIDs.
m_CurEventID--;
m_CmdBufferInfo[m_LastCmdBufferID].curEventID--;
AddDrawcall(draw, true);
}
{
if(GetDrawcallStack().size() > 1)
GetDrawcallStack().pop_back();
}
{
m_CmdBufferInfo[bakeId].draw = m_CmdBufferInfo[m_LastCmdBufferID].draw;
m_CmdBufferInfo[bakeId].curEventID = 0;
m_CmdBufferInfo[bakeId].eventCount = m_CmdBufferInfo[m_LastCmdBufferID].curEventID;
m_CmdBufferInfo[bakeId].drawCount = m_CmdBufferInfo[m_LastCmdBufferID].drawCount;
m_CmdBufferInfo[m_LastCmdBufferID].draw = NULL;
m_CmdBufferInfo[m_LastCmdBufferID].curEventID = 0;
m_CmdBufferInfo[m_LastCmdBufferID].eventCount = 0;
m_CmdBufferInfo[m_LastCmdBufferID].drawCount = 0;
}
}
return true;
@@ -423,11 +458,6 @@ bool WrappedVulkan::Serialise_vkResetCommandBuffer(VkCmdBuffer cmdBuffer, VkCmdB
{
cmd = GetResourceManager()->GetLiveHandle<VkCmdBuffer>(bakeId);
}
{
ResourceId liveBaked = GetResourceManager()->GetLiveID(bakeId);
m_CmdBufferInfo[liveBaked].device = VK_NULL_HANDLE;
}
ObjDisp(device)->ResetCommandBuffer(Unwrap(cmd), fl);
}
@@ -476,6 +506,9 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(
SERIALISE_ELEMENT(VkRenderPassBeginInfo, beginInfo, *pRenderPassBegin);
SERIALISE_ELEMENT(VkRenderPassContents, cont, contents);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -539,6 +572,9 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(
{
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -588,6 +624,9 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(
SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint);
SERIALISE_ELEMENT(ResourceId, pipeid, GetResID(pipeline));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -655,6 +694,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets(
SERIALISE_ELEMENT(uint32_t, numSets, setCount);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
ResourceId *descriptorIDs = new ResourceId[numSets];
VkDescriptorSet *sets = (VkDescriptorSet *)pDescriptorSets;
@@ -784,6 +826,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicViewportState(
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
SERIALISE_ELEMENT(ResourceId, stateid, GetResID(dynamicViewportState));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
dynamicViewportState = GetResourceManager()->GetLiveHandle<VkDynamicViewportState>(stateid);
@@ -832,6 +877,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicRasterState(
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
SERIALISE_ELEMENT(ResourceId, stateid, GetResID(dynamicRasterState));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
dynamicRasterState = GetResourceManager()->GetLiveHandle<VkDynamicRasterState>(stateid);
@@ -880,6 +928,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicColorBlendState(
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
SERIALISE_ELEMENT(ResourceId, stateid, GetResID(dynamicColorBlendState));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
dynamicColorBlendState = GetResourceManager()->GetLiveHandle<VkDynamicColorBlendState>(stateid);
@@ -927,6 +978,9 @@ bool WrappedVulkan::Serialise_vkCmdBindDynamicDepthStencilState(
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
SERIALISE_ELEMENT(ResourceId, stateid, GetResID(dynamicDepthStencilState));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
dynamicDepthStencilState = GetResourceManager()->GetLiveHandle<VkDynamicDepthStencilState>(stateid);
@@ -978,6 +1032,9 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(
SERIALISE_ELEMENT(uint32_t, start, startBinding);
SERIALISE_ELEMENT(uint32_t, count, bindingCount);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
vector<ResourceId> bufids;
vector<VkBuffer> bufs;
vector<VkDeviceSize> offs;
@@ -1072,6 +1129,9 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(
SERIALISE_ELEMENT(uint64_t, offs, offset);
SERIALISE_ELEMENT(VkIndexType, idxType, indexType);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
buffer = GetResourceManager()->GetLiveHandle<VkBuffer>(bufid);
@@ -1132,6 +1192,9 @@ bool WrappedVulkan::Serialise_vkCmdPipelineBarrier(
SERIALISE_ELEMENT(VkPipelineStageFlags, src, srcStageMask);
SERIALISE_ELEMENT(VkPipelineStageFlags, dest, destStageMask);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(VkBool32, region, byRegion);
SERIALISE_ELEMENT(uint32_t, memCount, memBarrierCount);
@@ -1282,6 +1345,9 @@ bool WrappedVulkan::Serialise_vkCmdDbgMarkerBegin(
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
m_pSerialiser->Serialise("Name", name);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == READING)
{
FetchDrawcall draw;
@@ -1313,7 +1379,10 @@ bool WrappedVulkan::Serialise_vkCmdDbgMarkerEnd(VkCmdBuffer cmdBuffer)
{
SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer));
if(m_State == READING && !m_CurEvents.empty())
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == READING && !m_CmdBufferInfo[m_LastCmdBufferID].curEvents.empty())
{
FetchDrawcall draw;
draw.name = "API Calls";
@@ -37,6 +37,9 @@ bool WrappedVulkan::Serialise_vkCmdDraw(
SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance);
SERIALISE_ELEMENT(uint32_t, instCount, instanceCount);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -112,6 +115,9 @@ bool WrappedVulkan::Serialise_vkCmdBlitImage(
SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage));
SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(VkTexFilter, f, filter);
SERIALISE_ELEMENT(uint32_t, count, regionCount);
@@ -184,6 +190,9 @@ bool WrappedVulkan::Serialise_vkCmdCopyImage(
SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage));
SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, count, regionCount);
SERIALISE_ELEMENT_ARR(VkImageCopy, regions, pRegions, count);
@@ -251,6 +260,9 @@ bool WrappedVulkan::Serialise_vkCmdCopyBufferToImage(
SERIALISE_ELEMENT(ResourceId, bufid, GetResID(srcBuffer));
SERIALISE_ELEMENT(ResourceId, imgid, GetResID(destImage));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, count, regionCount);
SERIALISE_ELEMENT_ARR(VkBufferImageCopy, regions, pRegions, count);
@@ -316,6 +328,9 @@ bool WrappedVulkan::Serialise_vkCmdCopyImageToBuffer(
SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer));
SERIALISE_ELEMENT(ResourceId, imgid, GetResID(srcImage));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(VkImageLayout, layout, srcImageLayout);
SERIALISE_ELEMENT(uint32_t, count, regionCount);
@@ -383,6 +398,9 @@ bool WrappedVulkan::Serialise_vkCmdCopyBuffer(
SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcBuffer));
SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destBuffer));
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, count, regionCount);
SERIALISE_ELEMENT_ARR(VkBufferCopy, regions, pRegions, count);
@@ -449,6 +467,9 @@ bool WrappedVulkan::Serialise_vkCmdClearColorImage(
SERIALISE_ELEMENT(VkImageLayout, layout, imageLayout);
SERIALISE_ELEMENT(VkClearColorValue, col, *pColor);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, count, rangeCount);
SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count);
@@ -514,6 +535,9 @@ bool WrappedVulkan::Serialise_vkCmdClearDepthStencilImage(
SERIALISE_ELEMENT(uint32_t, count, rangeCount);
SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
image = GetResourceManager()->GetLiveHandle<VkImage>(imgid);
@@ -573,6 +597,9 @@ bool WrappedVulkan::Serialise_vkCmdClearColorAttachment(
SERIALISE_ELEMENT(VkImageLayout, layout, imageLayout);
SERIALISE_ELEMENT(VkClearColorValue, col, *pColor);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, count, rectCount);
SERIALISE_ELEMENT_ARR(VkRect3D, rects, pRects, count);
@@ -651,6 +678,9 @@ bool WrappedVulkan::Serialise_vkCmdClearDepthStencilAttachment(
SERIALISE_ELEMENT(uint32_t, count, rectCount);
SERIALISE_ELEMENT_ARR(VkRect3D, rects, pRects, count);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -710,6 +740,9 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexed(
SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance);
SERIALISE_ELEMENT(uint32_t, instCount, instanceCount);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -760,6 +793,9 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndirect(
SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer));
SERIALISE_ELEMENT(uint64_t, offs, offset);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, cnt, count);
SERIALISE_ELEMENT(uint32_t, strd, stride);
@@ -815,6 +851,9 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(
SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer));
SERIALISE_ELEMENT(uint64_t, offs, offset);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
SERIALISE_ELEMENT(uint32_t, cnt, count);
SERIALISE_ELEMENT(uint32_t, strd, stride);
@@ -870,6 +909,9 @@ bool WrappedVulkan::Serialise_vkCmdDispatch(
SERIALISE_ELEMENT(uint32_t, Y, y);
SERIALISE_ELEMENT(uint32_t, Z, z);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
if(IsPartialCmd(cmdid) && InPartialRange())
@@ -916,6 +958,9 @@ bool WrappedVulkan::Serialise_vkCmdDispatchIndirect(
SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer));
SERIALISE_ELEMENT(uint64_t, offs, offset);
if(m_State < WRITING)
m_LastCmdBufferID = cmdid;
if(m_State == EXECUTING)
{
buffer = GetResourceManager()->GetLiveHandle<VkBuffer>(bufid);
@@ -177,9 +177,9 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(
AddDrawcall(draw, true);
// add command buffer draws under here
m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back());
GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back());
m_CurEventID++;
m_RootEventID++;
for(uint32_t c=0; c < numCmds; c++)
{
@@ -193,47 +193,47 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(
AddDrawcall(draw, true);
DrawcallTreeNode &d = m_DrawcallStack.back()->children.back();
DrawcallTreeNode &d = GetDrawcallStack().back()->children.back();
// copy DrawcallTreeNode children
d.children = m_CmdBufferInfo[cmdIds[c]].draw->children;
// assign new event and drawIDs
RefreshIDs(d.children, m_CurEventID, m_CurDrawcallID);
RefreshIDs(d.children, m_RootEventID, m_RootDrawcallID);
m_PartialReplayData.cmdBufferSubmits[cmdIds[c]].push_back(m_CurEventID);
m_PartialReplayData.cmdBufferSubmits[cmdIds[c]].push_back(m_RootEventID);
// 1 extra for the [0] virtual event for the command buffer
m_CurEventID += 1+m_CmdBufferInfo[cmdIds[c]].eventCount;
m_CurDrawcallID += m_CmdBufferInfo[cmdIds[c]].drawCount;
m_RootEventID += 1+m_CmdBufferInfo[cmdIds[c]].eventCount;
m_RootDrawcallID += m_CmdBufferInfo[cmdIds[c]].drawCount;
}
// the outer loop will increment the event ID but we've handled
// it ourselves, so 'undo' that.
m_CurEventID--;
m_RootEventID--;
// done adding command buffers
m_DrawcallStack.pop_back();
}
else if(m_State == EXECUTING)
{
m_CurEventID++;
m_RootEventID++;
uint32_t startEID = m_CurEventID;
uint32_t startEID = m_RootEventID;
// advance m_CurEventID to match the events added when reading
for(uint32_t c=0; c < numCmds; c++)
{
// 1 extra for the [0] virtual event for the command buffer
m_CurEventID += 1+m_CmdBufferInfo[cmdIds[c]].eventCount;
m_CurDrawcallID += m_CmdBufferInfo[cmdIds[c]].drawCount;
m_RootEventID += 1+m_CmdBufferInfo[cmdIds[c]].eventCount;
m_RootDrawcallID += m_CmdBufferInfo[cmdIds[c]].drawCount;
}
m_CurEventID--;
m_RootEventID--;
if(m_LastEventID < m_CurEventID)
if(m_LastEventID < m_RootEventID)
{
RDCDEBUG("Queue Submit partial replay %u < %u", m_LastEventID, m_CurEventID);
RDCDEBUG("Queue Submit partial replay %u < %u", m_LastEventID, m_RootEventID);
uint32_t eid = startEID;
@@ -889,19 +889,15 @@ VkResult WrappedVulkan::vkQueuePresentWSI(
map<int32_t, Chunk *> recordlist;
// ensure all command buffer records are disjoint and all present before queue submits
// ensure all command buffer records within the frame evne if recorded before, but
// otherwise order must be preserved (vs. queue submits and desc set updates)
for(size_t i=0; i < m_CmdBufferRecords.size(); i++)
{
recordlist.clear();
m_CmdBufferRecords[i]->Insert(recordlist);
RDCDEBUG("Adding %u chunks to file serialiser from command buffer %llu", (uint32_t)recordlist.size(), m_CmdBufferRecords[i]->GetResourceID());
for(auto it = recordlist.begin(); it != recordlist.end(); ++it)
m_pFileSerialiser->Insert(it->second);
}
recordlist.clear();
m_FrameCaptureRecord->Insert(recordlist);
RDCDEBUG("Flushing %u chunks to file serialiser from context record", (uint32_t)recordlist.size());