diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index e7a277b52..1164ef9dc 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -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 &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 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); } diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index ba06c2939..6bba5e8c3 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -191,16 +191,20 @@ private: vector< pair > imgtransitions; // used on replay + vector curEvents; + list 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 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 m_CurEvents, m_Events; + vector 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 &nodes, uint32_t baseEventID, uint32_t baseDrawID); list m_DrawcallStack; + + list &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); diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index e62f0e557..55b298585 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -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(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(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(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(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(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 bufids; vector bufs; vector 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(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"; diff --git a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp index 30f7e8b9f..8e68072a8 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp @@ -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(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(bufid); diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index a59a1ec3c..089e2e2cb 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -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; diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index eba545841..dd106f9e7 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -889,19 +889,15 @@ VkResult WrappedVulkan::vkQueuePresentWSI( map 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());