From f442543ab5f20429833e8ab68106e3312e5668d3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 17 Aug 2017 13:03:19 +0100 Subject: [PATCH] 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. --- renderdoc/driver/vulkan/vk_core.h | 15 +++++++++++++-- renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp | 12 ++++++------ .../driver/vulkan/wrappers/vk_queue_funcs.cpp | 12 +++++++++--- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index f45c2bf3e..d75cffaf7 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -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 - map > 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 + map > cmdBufferSubmits; // This is just the ResourceId of the original parent command buffer // and it's baked id. diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 2a1135c94..f72fc1d9c 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -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 &baseEvents = m_Partial[p].cmdBufferSubmits[bakeId]; + const vector &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 = diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index 89a83c6ff..29e2baf1f 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -228,11 +228,17 @@ bool WrappedVulkan::Serialise_vkQueueSubmit(Serialiser *localSerialiser, VkQueue for(size_t e = 0; e < cmdBufInfo.draw->executedCmds.size(); e++) { - vector &submits = + vector &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;