mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-21 13:15:57 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user