Make sure not to offset secondary cmd buf submissions multiple times

* When a primary command buffer is submitted that contained some
  secondary executes, we offset their executes to be 'absolute'
  root-relative events so they know when they're being partially
  replayed.
* If the same secondary is executed in multiple primaries that are
  submitted separately, we don't want to apply the same offset over and
  over, instead we mark an execute as updated and only offset 'new'
  executions.
This commit is contained in:
baldurk
2017-08-17 13:03:19 +01:00
parent f4951e28a4
commit f442543ab5
3 changed files with 28 additions and 11 deletions
+13 -2
View File
@@ -472,6 +472,13 @@ private:
ePartialNum
};
struct Submission
{
Submission(uint32_t eid) : baseEvent(eid), rebased(false) {}
uint32_t baseEvent = 0;
bool rebased = false;
};
struct PartialReplayData
{
PartialReplayData() { Reset(); }
@@ -512,8 +519,12 @@ private:
// vkCmd chunks) is NOT unique.
// However, a single baked command list can be submitted multiple
// times - so we have to have a list of base events
// Map from bakeID -> vector<baseEventID>
map<ResourceId, vector<uint32_t> > cmdBufferSubmits;
// Note in the case of secondary command buffers we mark when these
// are rebased to 'absolute' event IDs, since they could be submitted
// multiple times in the frame and we don't want to rebase all of
// them each time.
// Map from bakeID -> vector<Submission>
map<ResourceId, vector<Submission> > cmdBufferSubmits;
// This is just the ResourceId of the original parent command buffer
// and it's baked id.
@@ -513,19 +513,19 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(Serialiser *localSerialiser,
// check for partial execution of this command buffer
for(int p = 0; p < ePartialNum; p++)
{
const vector<uint32_t> &baseEvents = m_Partial[p].cmdBufferSubmits[bakeId];
const vector<Submission> &submissions = m_Partial[p].cmdBufferSubmits[bakeId];
for(auto it = baseEvents.begin(); it != baseEvents.end(); ++it)
for(auto it = submissions.begin(); it != submissions.end(); ++it)
{
if(*it <= m_LastEventID && m_LastEventID < (*it + length))
if(it->baseEvent <= m_LastEventID && m_LastEventID < (it->baseEvent + length))
{
#if ENABLED(VERBOSE_PARTIAL_REPLAY)
RDCDEBUG("vkBegin - partial detected %u < %u < %u, %llu -> %llu", *it, m_LastEventID,
*it + length, cmdId, bakeId);
RDCDEBUG("vkBegin - partial detected %u < %u < %u, %llu -> %llu", it->baseEvent,
m_LastEventID, it->baseEvent + length, cmdId, bakeId);
#endif
m_Partial[p].partialParent = cmdId;
m_Partial[p].baseEvent = *it;
m_Partial[p].baseEvent = it->baseEvent;
m_Partial[p].renderPassActive = false;
m_Partial[p].partialDevice = device;
m_Partial[p].resultPartialCmdPool =
@@ -228,11 +228,17 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(Serialiser *localSerialiser, VkQueue
for(size_t e = 0; e < cmdBufInfo.draw->executedCmds.size(); e++)
{
vector<uint32_t> &submits =
vector<Submission> &submits =
m_Partial[Secondary].cmdBufferSubmits[cmdBufInfo.draw->executedCmds[e]];
for(size_t s = 0; s < submits.size(); s++)
submits[s] += m_RootEventID;
{
if(!submits[s].rebased)
{
submits[s].baseEvent += m_RootEventID;
submits[s].rebased = true;
}
}
}
for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++)
@@ -242,7 +248,7 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(Serialiser *localSerialiser, VkQueue
}
// only primary command buffers can be submitted
m_Partial[Primary].cmdBufferSubmits[cmdIds[c]].push_back(m_RootEventID);
m_Partial[Primary].cmdBufferSubmits[cmdIds[c]].push_back(Submission(m_RootEventID));
m_RootEventID += cmdBufInfo.eventCount;
m_RootDrawcallID += cmdBufInfo.drawCount;