From a1aeebb4628b45ad970203505e86061027a2ed09 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 2 Oct 2017 15:14:12 +0100 Subject: [PATCH] Update command-recording function wrappers --- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 2661 ++++++++--------- 1 file changed, 1293 insertions(+), 1368 deletions(-) diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 83b23432b..c54f2d332 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -28,7 +28,7 @@ std::vector WrappedVulkan::GetImplicitRenderPassBarriers(u { ResourceId rp, fb; - if(m_State == EXECUTING) + if(IsActiveReplaying(m_State)) { rp = m_RenderState.renderPass; fb = m_RenderState.framebuffer; @@ -62,7 +62,7 @@ std::vector WrappedVulkan::GetImplicitRenderPassBarriers(u } else { - if(m_State == EXECUTING) + if(IsActiveReplaying(m_State)) subpass = m_RenderState.subpass; else subpass = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass; @@ -316,21 +316,21 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) // Command pool functions -bool WrappedVulkan::Serialise_vkCreateCommandPool(Serialiser *localSerialiser, VkDevice device, +template +bool WrappedVulkan::Serialise_vkCreateCommandPool(SerialiserType &ser, VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCmdPool) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkCommandPoolCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pCmdPool)); + SERIALISE_ELEMENT(device); + SERIALISE_ELEMENT_LOCAL(CreateInfo, *pCreateInfo); + SERIALISE_ELEMENT_LOCAL(CmdPool, GetResID(*pCmdPool)); - if(m_State == READING) + if(IsReplayingAndReading()) { - device = GetResourceManager()->GetLiveHandle(devId); VkCommandPool pool = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), &info, NULL, &pool); + VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), &CreateInfo, NULL, &pool); if(ret != VK_SUCCESS) { @@ -339,7 +339,7 @@ bool WrappedVulkan::Serialise_vkCreateCommandPool(Serialiser *localSerialiser, V else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); - GetResourceManager()->AddLiveResource(id, pool); + GetResourceManager()->AddLiveResource(CmdPool, pool); } } @@ -358,15 +358,15 @@ VkResult WrappedVulkan::vkCreateCommandPool(VkDevice device, { ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pCmdPool); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { Chunk *chunk = NULL; { CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CREATE_CMD_POOL); - Serialise_vkCreateCommandPool(localSerialiser, device, pCreateInfo, NULL, pCmdPool); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCreateCommandPool); + Serialise_vkCreateCommandPool(ser, device, pCreateInfo, NULL, pCmdPool); chunk = scope.Get(); } @@ -422,7 +422,7 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, else SetDispatchTableOverMagicNumber(device, unwrappedReal); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pCommandBuffers[i]); @@ -460,185 +460,196 @@ VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, return ret; } -bool WrappedVulkan::Serialise_vkBeginCommandBuffer(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) { - SERIALISE_ELEMENT(ResourceId, cmdId, GetResID(commandBuffer)); - - ResourceId bakedCmdId; - VkCommandBufferAllocateInfo allocInfo; + ResourceId BakedCommandBuffer; + VkCommandBufferAllocateInfo AllocateInfo; VkDevice device = VK_NULL_HANDLE; - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdId); + VkResourceRecord *record = GetRecord(commandBuffer); RDCASSERT(record->bakedCommands); if(record->bakedCommands) - bakedCmdId = record->bakedCommands->GetResourceID(); + BakedCommandBuffer = record->bakedCommands->GetResourceID(); RDCASSERT(record->cmdInfo); device = record->cmdInfo->device; - allocInfo = record->cmdInfo->allocInfo; + AllocateInfo = record->cmdInfo->allocInfo; } - SERIALISE_ELEMENT(VkCommandBufferBeginInfo, info, *pBeginInfo); - SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); + SERIALISE_ELEMENT_LOCAL(CommandBuffer, GetResID(commandBuffer)); + SERIALISE_ELEMENT_LOCAL(BeginInfo, *pBeginInfo); + SERIALISE_ELEMENT(BakedCommandBuffer); + SERIALISE_ELEMENT(device); + SERIALISE_ELEMENT(AllocateInfo); - if(m_State < WRITING) + if(IsReplayingAndReading()) { - m_LastCmdBufferID = cmdId; - } + m_LastCmdBufferID = CommandBuffer; - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - localSerialiser->Serialise("allocInfo", allocInfo); + m_BakedCmdBufferInfo[m_LastCmdBufferID].level = m_BakedCmdBufferInfo[BakedCommandBuffer].level = + AllocateInfo.level; + m_BakedCmdBufferInfo[m_LastCmdBufferID].beginFlags = + m_BakedCmdBufferInfo[BakedCommandBuffer].beginFlags = BeginInfo.flags; + m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount = 0; - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); - - m_BakedCmdBufferInfo[cmdId].level = m_BakedCmdBufferInfo[bakeId].level = allocInfo.level; - m_BakedCmdBufferInfo[cmdId].beginFlags = m_BakedCmdBufferInfo[bakeId].beginFlags = info.flags; - m_BakedCmdBufferInfo[cmdId].markerCount = 0; - } - - if(m_State == EXECUTING) - { - const uint32_t length = m_BakedCmdBufferInfo[bakeId].eventCount; - - bool partial = false; - int partialType = ePartialNum; - - // check for partial execution of this command buffer - for(int p = 0; p < ePartialNum; p++) + if(IsActiveReplaying(m_State)) { - const vector &submissions = m_Partial[p].cmdBufferSubmits[bakeId]; + const uint32_t length = m_BakedCmdBufferInfo[BakedCommandBuffer].eventCount; - for(auto it = submissions.begin(); it != submissions.end(); ++it) + bool partial = false; + int partialType = ePartialNum; + + // check for partial execution of this command buffer + for(int p = 0; p < ePartialNum; p++) { - if(it->baseEvent <= m_LastEventID && m_LastEventID < (it->baseEvent + length)) + const std::vector &submissions = + m_Partial[p].cmdBufferSubmits[BakedCommandBuffer]; + + for(auto it = submissions.begin(); it != submissions.end(); ++it) { + 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->baseEvent, - m_LastEventID, it->baseEvent + length, cmdId, bakeId); + RDCDEBUG("vkBegin - partial detected %u < %u < %u, %llu -> %llu", it->baseEvent, + m_LastEventID, it->baseEvent + length, m_LastCmdBufferID, BakedCommandBuffer); #endif - m_Partial[p].partialParent = cmdId; - m_Partial[p].baseEvent = it->baseEvent; - m_Partial[p].renderPassActive = false; - m_Partial[p].partialDevice = device; - m_Partial[p].resultPartialCmdPool = - (VkCommandPool)(uint64_t)GetResourceManager()->GetNonDispWrapper(allocInfo.commandPool); + m_Partial[p].partialParent = BakedCommandBuffer; + m_Partial[p].baseEvent = it->baseEvent; + m_Partial[p].renderPassActive = false; + m_Partial[p].partialDevice = device; + m_Partial[p].resultPartialCmdPool = AllocateInfo.commandPool; - partial = true; - partialType = p; + partial = true; + partialType = p; + } } } - } - if(partial || (m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())) - { - // pull all re-recorded commands from our own device and command pool for easier cleanup - if(!partial) + if(partial || (m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())) { - device = GetDev(); - allocInfo.commandPool = Unwrap(m_InternalCmds.cmdpool); - } + // pull all re-recorded commands from our own device and command pool for easier cleanup + if(!partial) + { + device = GetDev(); + AllocateInfo.commandPool = Unwrap(m_InternalCmds.cmdpool); + } - VkCommandBuffer cmd = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); + VkCommandBuffer cmd = VK_NULL_HANDLE; + VkCommandBufferAllocateInfo unwrappedInfo = AllocateInfo; + unwrappedInfo.commandPool = Unwrap(unwrappedInfo.commandPool); + VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &unwrappedInfo, &cmd); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - GetResourceManager()->WrapResource(Unwrap(device), cmd); - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + GetResourceManager()->WrapResource(Unwrap(device), cmd); + } - if(partial) - { - m_Partial[partialType].resultPartialCmdBuffer = cmd; - } - else - { - // we store under both baked and non baked ID. - // The baked ID is the 'real' entry, the non baked is simply so it - // can be found in the subsequent serialised commands that ref the - // non-baked ID. The baked ID is referenced by the submit itself. - // - // In vkEndCommandBuffer we erase the non-baked reference, and since - // we know you can only be recording a command buffer once at a time - // (even if it's baked to several command buffers in the frame) - // there's no issue with clashes here. - m_RerecordCmds[bakeId] = cmd; - m_RerecordCmds[cmdId] = cmd; - } + if(partial) + { + m_Partial[partialType].resultPartialCmdBuffer = cmd; + } + else + { + // we store under both baked and non baked ID. + // The baked ID is the 'real' entry, the non baked is simply so it + // can be found in the subsequent serialised commands that ref the + // non-baked ID. The baked ID is referenced by the submit itself. + // + // In vkEndCommandBuffer we erase the non-baked reference, and since + // we know you can only be recording a command buffer once at a time + // (even if it's baked to several command buffers in the frame) + // there's no issue with clashes here. + m_RerecordCmds[BakedCommandBuffer] = cmd; + m_RerecordCmds[m_LastCmdBufferID] = cmd; + } - m_BakedCmdBufferInfo[GetResID(cmd)].level = allocInfo.level; - m_BakedCmdBufferInfo[GetResID(cmd)].beginFlags = info.flags; + m_BakedCmdBufferInfo[GetResID(cmd)].level = AllocateInfo.level; + m_BakedCmdBufferInfo[GetResID(cmd)].beginFlags = BeginInfo.flags; - // add one-time submit flag as this partial cmd buffer will only be submitted once - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - if(allocInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) - info.flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + // add one-time submit flag as this partial cmd buffer will only be submitted once + BeginInfo.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + if(AllocateInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) + BeginInfo.flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &info); - } - - m_BakedCmdBufferInfo[cmdId].curEventID = 0; - } - else if(m_State == READING) - { - // remove one-time submit flag as we will want to submit many - info.flags &= ~VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - if(allocInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) - info.flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - - VkCommandBuffer cmd = VK_NULL_HANDLE; - - if(!GetResourceManager()->HasLiveResource(bakeId)) - { - VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); - - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd); - GetResourceManager()->AddLiveResource(bakeId, cmd); + ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &BeginInfo); } // whenever a vkCmd command-building chunk asks for the command buffer, it // will get our baked version. - GetResourceManager()->ReplaceResource(cmdId, bakeId); + if(GetResourceManager()->HasReplacement(m_LastCmdBufferID)) + GetResourceManager()->RemoveReplacement(m_LastCmdBufferID); + + GetResourceManager()->ReplaceResource(m_LastCmdBufferID, BakedCommandBuffer); + + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; + m_BakedCmdBufferInfo[BakedCommandBuffer].curEventID = 0; } else { - cmd = GetResourceManager()->GetLiveHandle(bakeId); + // remove one-time submit flag as we will want to submit many + BeginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + if(AllocateInfo.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) + BeginInfo.flags |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + + VkCommandBuffer cmd = VK_NULL_HANDLE; + + if(!GetResourceManager()->HasLiveResource(BakedCommandBuffer)) + { + VkCommandBufferAllocateInfo unwrappedInfo = AllocateInfo; + unwrappedInfo.commandPool = Unwrap(unwrappedInfo.commandPool); + VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &unwrappedInfo, &cmd); + + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd); + GetResourceManager()->AddLiveResource(BakedCommandBuffer, cmd); + } + + // whenever a vkCmd command-building chunk asks for the command buffer, it + // will get our baked version. + if(GetResourceManager()->HasReplacement(m_LastCmdBufferID)) + GetResourceManager()->RemoveReplacement(m_LastCmdBufferID); + + GetResourceManager()->ReplaceResource(m_LastCmdBufferID, BakedCommandBuffer); + } + else + { + cmd = GetResourceManager()->GetLiveHandle(BakedCommandBuffer); + } + + // propagate any name there might be + if(m_CreationInfo.m_Names.find(m_LastCmdBufferID) != m_CreationInfo.m_Names.end()) + m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(BakedCommandBuffer)] = + m_CreationInfo.m_Names[m_LastCmdBufferID]; + + { + VulkanDrawcallTreeNode *draw = new VulkanDrawcallTreeNode; + m_BakedCmdBufferInfo[BakedCommandBuffer].draw = draw; + + // On queue submit we increment all child events/drawcalls by + // m_RootEventID and insert them into the tree. + m_BakedCmdBufferInfo[BakedCommandBuffer].curEventID = 0; + m_BakedCmdBufferInfo[BakedCommandBuffer].eventCount = 0; + m_BakedCmdBufferInfo[BakedCommandBuffer].drawCount = 0; + + m_BakedCmdBufferInfo[BakedCommandBuffer].drawStack.push_back(draw); + } + + ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &BeginInfo); } - - // propagate any name there might be - if(m_CreationInfo.m_Names.find(cmdId) != m_CreationInfo.m_Names.end()) - m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(bakeId)] = m_CreationInfo.m_Names[cmdId]; - - { - VulkanDrawcallTreeNode *draw = new VulkanDrawcallTreeNode; - m_BakedCmdBufferInfo[cmdId].draw = draw; - - // On queue submit we increment all child events/drawcalls by - // m_RootEventID and insert them into the tree. - m_BakedCmdBufferInfo[cmdId].curEventID = 0; - m_BakedCmdBufferInfo[cmdId].eventCount = 0; - m_BakedCmdBufferInfo[cmdId].drawCount = 0; - - m_BakedCmdBufferInfo[cmdId].drawStack.push_back(draw); - } - - ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &info); } return true; @@ -669,8 +680,8 @@ VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer, { CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BEGIN_CMD_BUFFER); - Serialise_vkBeginCommandBuffer(localSerialiser, commandBuffer, pBeginInfo); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkBeginCommandBuffer); + Serialise_vkBeginCommandBuffer(ser, commandBuffer, pBeginInfo); record->AddChunk(scope.Get()); } @@ -699,104 +710,97 @@ VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer, return ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), pBeginInfo); } -bool WrappedVulkan::Serialise_vkEndCommandBuffer(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer) +template +bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + ResourceId BakedCommandBuffer; - ResourceId bakedCmdId; - - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdid); + VkResourceRecord *record = GetRecord(commandBuffer); RDCASSERT(record->bakedCommands); if(record->bakedCommands) - bakedCmdId = record->bakedCommands->GetResourceID(); + BakedCommandBuffer = record->bakedCommands->GetResourceID(); } - SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); + SERIALISE_ELEMENT_LOCAL(CommandBuffer, GetResID(commandBuffer)); + SERIALISE_ELEMENT(BakedCommandBuffer); - if(m_State < WRITING) + if(IsReplayingAndReading()) { - m_LastCmdBufferID = cmdid; - } + m_LastCmdBufferID = CommandBuffer; - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); + if(ShouldRerecordCmd(BakedCommandBuffer)) + { + commandBuffer = RerecordCmdBuf(BakedCommandBuffer); #if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("Ending partial command buffer for %llu baked to %llu", cmdid, bakeId); + RDCDEBUG("Ending partial command buffer for %llu baked to %llu", m_LastCmdBufferID, + BakedCommandBuffer); #endif - bool recordAll = m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds(); + bool recordAll = m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds(); - if(!recordAll && m_Partial[Primary].partialParent == cmdid && - m_Partial[Primary].renderPassActive) - { - uint32_t numSubpasses = - (uint32_t)m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size(); + if(!recordAll && m_Partial[Primary].partialParent == BakedCommandBuffer && + m_Partial[Primary].renderPassActive) + { + uint32_t numSubpasses = + (uint32_t)m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size(); - for(uint32_t sub = m_RenderState.subpass; sub < numSubpasses - 1; sub++) - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), VK_SUBPASS_CONTENTS_INLINE); + for(uint32_t sub = m_RenderState.subpass; sub < numSubpasses - 1; sub++) + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), VK_SUBPASS_CONTENTS_INLINE); - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + } + + if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) + for(int i = 0; i < m_BakedCmdBufferInfo[BakedCommandBuffer].markerCount; i++) + ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); + + ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); + + // erase the non-baked reference to this command buffer so that we don't have + // duplicates when it comes time to clean up. See above in vkBeginCommandBuffer + m_RerecordCmds.erase(m_LastCmdBufferID); + + if(m_Partial[Primary].partialParent == BakedCommandBuffer) + m_Partial[Primary].partialParent = ResourceId(); } - if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) - for(int i = 0; i < m_BakedCmdBufferInfo[cmdid].markerCount; i++) - ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; + } + else + { + commandBuffer = GetResourceManager()->GetLiveHandle(BakedCommandBuffer); ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); - // erase the non-baked reference to this command buffer so that we don't have - // duplicates when it comes time to clean up. See above in vkBeginCommandBuffer - m_RerecordCmds.erase(cmdid); + if(!m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) + { + DrawcallDescription draw; + draw.name = "API Calls"; + draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; - if(m_Partial[Primary].partialParent == cmdid) - m_Partial[Primary].partialParent = ResourceId(); - } + AddDrawcall(draw, true); - m_BakedCmdBufferInfo[cmdid].curEventID = 0; - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(bakeId); + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; + } - GetResourceManager()->RemoveReplacement(cmdid); + { + if(GetDrawcallStack().size() > 1) + GetDrawcallStack().pop_back(); + } - ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); + { + m_BakedCmdBufferInfo[BakedCommandBuffer].eventCount = + m_BakedCmdBufferInfo[BakedCommandBuffer].curEventID; + m_BakedCmdBufferInfo[BakedCommandBuffer].curEventID = 0; - if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) - { - DrawcallDescription draw; - draw.name = "API Calls"; - draw.flags |= DrawFlags::SetMarker | DrawFlags::APICalls; - - AddDrawcall(draw, true); - - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - } - - { - if(GetDrawcallStack().size() > 1) - GetDrawcallStack().pop_back(); - } - - { - m_BakedCmdBufferInfo[bakeId].draw = m_BakedCmdBufferInfo[m_LastCmdBufferID].draw; - m_BakedCmdBufferInfo[bakeId].curEvents = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents; - m_BakedCmdBufferInfo[bakeId].debugMessages = - m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages; - m_BakedCmdBufferInfo[bakeId].curEventID = 0; - m_BakedCmdBufferInfo[bakeId].eventCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID; - m_BakedCmdBufferInfo[bakeId].drawCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount; - - m_BakedCmdBufferInfo[m_LastCmdBufferID].draw = NULL; - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].eventCount = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].eventCount = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount = 0; + } } } @@ -815,9 +819,9 @@ VkResult WrappedVulkan::vkEndCommandBuffer(VkCommandBuffer commandBuffer) { CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(END_CMD_BUFFER); - Serialise_vkEndCommandBuffer(localSerialiser, commandBuffer); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkEndCommandBuffer); + Serialise_vkEndCommandBuffer(ser, commandBuffer); record->AddChunk(scope.Get()); } @@ -858,72 +862,72 @@ VkResult WrappedVulkan::vkResetCommandBuffer(VkCommandBuffer commandBuffer, // Command buffer building functions -bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(SerialiserType &ser, VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo *pRenderPassBegin, VkSubpassContents contents) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkRenderPassBeginInfo, beginInfo, *pRenderPassBegin); - SERIALISE_ELEMENT(VkSubpassContents, cont, contents); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_LOCAL(RenderPassBegin, *pRenderPassBegin); + SERIALISE_ELEMENT(contents); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + VkRenderPassBeginInfo unwrappedInfo = RenderPassBegin; + unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); + unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); + + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); - m_Partial[Primary].renderPassActive = true; - ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); + m_Partial[Primary].renderPassActive = true; + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); - m_RenderState.subpass = 0; + m_RenderState.subpass = 0; - m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; - m_RenderState.renderArea = beginInfo.renderArea; + m_RenderState.renderPass = GetResID(RenderPassBegin.renderPass); + m_RenderState.framebuffer = GetResID(RenderPassBegin.framebuffer); + m_RenderState.renderArea = RenderPassBegin.renderArea; + + std::vector imgBarriers = GetImplicitRenderPassBarriers(); + + ResourceId cmd = GetResID(commandBuffer); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), imgBarriers.data()); + } + } + else + { + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); + + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = GetResID(RenderPassBegin.renderPass); + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = + GetResID(RenderPassBegin.framebuffer); std::vector imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + (uint32_t)imgBarriers.size(), imgBarriers.data()); + + AddEvent(); + DrawcallDescription draw; + draw.name = + StringFormat::Fmt("vkCmdBeginRenderPass(%s)", MakeRenderPassOpString(false).c_str()); + draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass; + + AddDrawcall(draw, true); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); - - // track while reading, for fetching the right set of outputs in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = - GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = - GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; - - std::vector imgBarriers = GetImplicitRenderPassBarriers(); - - ResourceId cmd = GetResID(commandBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - const string desc = localSerialiser->GetDebugStr(); - - string opDesc = MakeRenderPassOpString(false); - - AddEvent(desc); - DrawcallDescription draw; - draw.name = StringFormat::Fmt("vkCmdBeginRenderPass(%s)", opDesc.c_str()); - draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass; - - AddDrawcall(draw, true); - } return true; } @@ -939,14 +943,14 @@ void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(BEGIN_RENDERPASS); - Serialise_vkCmdBeginRenderPass(localSerialiser, commandBuffer, pRenderPassBegin, contents); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginRenderPass); + Serialise_vkCmdBeginRenderPass(ser, commandBuffer, pRenderPassBegin, contents); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read); @@ -972,62 +976,61 @@ void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, } } -bool WrappedVulkan::Serialise_vkCmdNextSubpass(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdNextSubpass(SerialiserType &ser, VkCommandBuffer commandBuffer, VkSubpassContents contents) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkSubpassContents, cont, contents); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(contents); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - // don't do anything if we're executing a single draw, NextSubpass is meaningless (and invalid - // on a partial render pass) - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid) && m_FirstEventID != m_LastEventID) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); + // don't do anything if we're executing a single draw, NextSubpass is meaningless (and invalid + // on a partial render pass) + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID) && + m_FirstEventID != m_LastEventID) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); - m_RenderState.subpass++; + m_RenderState.subpass++; - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); + + std::vector imgBarriers = GetImplicitRenderPassBarriers(); + + ResourceId cmd = GetResID(commandBuffer); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), imgBarriers.data()); + } + } + else + { + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); + + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++; std::vector imgBarriers = GetImplicitRenderPassBarriers(); ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); + + AddEvent(); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass); + draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass | DrawFlags::EndPass; + + AddDrawcall(draw, true); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); - - // track while reading, for fetching the right set of outputs in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++; - - std::vector imgBarriers = GetImplicitRenderPassBarriers(); - - ResourceId cmd = GetResID(commandBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - const string desc = localSerialiser->GetDebugStr(); - - AddEvent(desc); - DrawcallDescription draw; - draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass); - draw.flags |= DrawFlags::PassBoundary | DrawFlags::BeginPass | DrawFlags::EndPass; - - AddDrawcall(draw, true); - } return true; } @@ -1038,36 +1041,48 @@ void WrappedVulkan::vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassCon ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(NEXT_SUBPASS); - Serialise_vkCmdNextSubpass(localSerialiser, commandBuffer, contents); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdNextSubpass); + Serialise_vkCmdNextSubpass(ser, commandBuffer, contents); record->AddChunk(scope.Get()); } } -bool WrappedVulkan::Serialise_vkCmdEndRenderPass(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer) +template +bool WrappedVulkan::Serialise_vkCmdEndRenderPass(SerialiserType &ser, VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(commandBuffer); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - m_Partial[Primary].renderPassActive = false; + if(IsActiveReplaying(m_State)) + { + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + m_Partial[Primary].renderPassActive = false; + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + + std::vector imgBarriers = GetImplicitRenderPassBarriers(~0U); + + ResourceId cmd = GetResID(commandBuffer); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), imgBarriers.data()); + } + } + else + { ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); std::vector imgBarriers = GetImplicitRenderPassBarriers(~0U); @@ -1075,36 +1090,20 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass(Serialiser *localSerialiser, ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); + + AddEvent(); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("vkCmdEndRenderPass(%s)", MakeRenderPassOpString(true).c_str()); + draw.flags |= DrawFlags::PassBoundary | DrawFlags::EndPass; + + AddDrawcall(draw, true); + + // track while reading, reset this to empty so AddDrawcall sets no outputs, + // but only AFTER the above AddDrawcall (we want it grouped together) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId(); + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId(); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - - std::vector imgBarriers = GetImplicitRenderPassBarriers(~0U); - - ResourceId cmd = GetResID(commandBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - const string desc = localSerialiser->GetDebugStr(); - - string opDesc = MakeRenderPassOpString(true); - - AddEvent(desc); - DrawcallDescription draw; - draw.name = StringFormat::Fmt("vkCmdEndRenderPass(%s)", opDesc.c_str()); - draw.flags |= DrawFlags::PassBoundary | DrawFlags::EndPass; - - AddDrawcall(draw, true); - - // track while reading, reset this to empty so AddDrawcall sets no outputs, - // but only AFTER the above AddDrawcall (we want it grouped together) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId(); - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId(); - } return true; } @@ -1115,14 +1114,14 @@ void WrappedVulkan::vkCmdEndRenderPass(VkCommandBuffer commandBuffer) ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(END_RENDERPASS); - Serialise_vkCmdEndRenderPass(localSerialiser, commandBuffer); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndRenderPass); + Serialise_vkCmdEndRenderPass(ser, commandBuffer); record->AddChunk(scope.Get()); @@ -1147,94 +1146,95 @@ void WrappedVulkan::vkCmdEndRenderPass(VkCommandBuffer commandBuffer) } } -bool WrappedVulkan::Serialise_vkCmdBindPipeline(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); - SERIALISE_ELEMENT(ResourceId, pipeid, GetResID(pipeline)); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(pipelineBindPoint); + SERIALISE_ELEMENT(pipeline); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - pipeline = GetResourceManager()->GetLiveHandle(pipeid); - commandBuffer = RerecordCmdBuf(cmdid); - - ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); - - ResourceId liveid = GetResID(pipeline); - - if(bind == VK_PIPELINE_BIND_POINT_COMPUTE) + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) { - m_RenderState.compute.pipeline = liveid; + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + ResourceId liveid = GetResID(pipeline); + + if(pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE) + { + m_RenderState.compute.pipeline = liveid; + } + else + { + m_RenderState.graphics.pipeline = liveid; + + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT]) + { + m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR]) + { + m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH]) + { + m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS]) + { + m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBiasConstantFactor; + m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; + m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].depthBiasSlopeFactor; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) + { + memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, + sizeof(float) * 4); + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) + { + m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; + m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) + { + m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.compareMask; + m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.compareMask; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) + { + m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.writeMask; + m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.writeMask; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) + { + m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.reference; + m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.reference; + } + } } else { - m_RenderState.graphics.pipeline = liveid; - - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT]) - { - m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR]) - { - m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH]) - { - m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS]) - { - m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBiasConstantFactor; - m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; - m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].depthBiasSlopeFactor; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) - { - memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, - sizeof(float) * 4); - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) - { - m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; - m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) - { - m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.compareMask; - m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.compareMask; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) - { - m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.writeMask; - m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.writeMask; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) - { - m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.reference; - m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.reference; - } + commandBuffer = VK_NULL_HANDLE; } } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - pipeline = GetResourceManager()->GetLiveHandle(pipeid); + else + { + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline = GetResID(pipeline); + } - // track while reading, as we need to bind current topology & index byte width in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline = GetResID(pipeline); - - ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); + if(commandBuffer != VK_NULL_HANDLE) + ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(pipeline)); } return true; @@ -1247,171 +1247,136 @@ void WrappedVulkan::vkCmdBindPipeline(VkCommandBuffer commandBuffer, ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(pipeline)); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_PIPELINE); - Serialise_vkCmdBindPipeline(localSerialiser, commandBuffer, pipelineBindPoint, pipeline); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindPipeline); + Serialise_vkCmdBindPipeline(ser, commandBuffer, pipelineBindPoint, pipeline); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(pipeline), eFrameRef_Read); } } +template bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets( - Serialiser *localSerialiser, VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, - uint32_t setCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, + SerialiserType &ser, VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, + const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t *pDynamicOffsets) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, layoutid, GetResID(layout)); - SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); - SERIALISE_ELEMENT(uint32_t, first, firstSet); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(pipelineBindPoint); + SERIALISE_ELEMENT(layout); + SERIALISE_ELEMENT(firstSet); + SERIALISE_ELEMENT_ARRAY(pDescriptorSets, setCount); + SERIALISE_ELEMENT_ARRAY(pDynamicOffsets, dynamicOffsetCount); - SERIALISE_ELEMENT(uint32_t, numSets, setCount); + Serialise_DebugMessages(ser); - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - ResourceId *descriptorIDs = NULL; - - VkDescriptorSet *sets = (VkDescriptorSet *)pDescriptorSets; - if(m_State < WRITING) + if(IsReplayingAndReading()) { - descriptorIDs = new ResourceId[numSets]; - sets = new VkDescriptorSet[numSets]; - } + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - for(uint32_t i = 0; i < numSets; i++) - { - ResourceId id; - if(m_State >= WRITING) - id = GetResID(sets[i]); - - localSerialiser->Serialise("DescriptorSet", id); - - if(m_State < WRITING) + if(IsActiveReplaying(m_State)) { - descriptorIDs[i] = id; - sets[i] = GetResourceManager()->GetLiveHandle(descriptorIDs[i]); - descriptorIDs[i] = GetResID(sets[i]); - sets[i] = Unwrap(sets[i]); - } - } - - SERIALISE_ELEMENT(uint32_t, offsCount, dynamicOffsetCount); - SERIALISE_ELEMENT_ARR_OPT(uint32_t, offs, pDynamicOffsets, offsCount, offsCount > 0); - - if(m_State == EXECUTING) - { - layout = GetResourceManager()->GetLiveHandle(layoutid); - - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); - - ObjDisp(commandBuffer) - ->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, - offsCount, offs); - - vector &descsets = - (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) ? m_RenderState.graphics.descSets - : m_RenderState.compute.descSets; - - // expand as necessary - if(descsets.size() < first + numSets) - descsets.resize(first + numSets); - - const vector &descSetLayouts = - m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts; - - uint32_t *offsIter = offs; - uint32_t dynConsumed = 0; - - // consume the offsets linearly along the descriptor set layouts - for(uint32_t i = 0; i < numSets; i++) + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) { - descsets[first + i].descSet = descriptorIDs[i]; - uint32_t dynCount = m_CreationInfo.m_DescSetLayout[descSetLayouts[first + i]].dynamicCount; - descsets[first + i].offsets.assign(offsIter, offsIter + dynCount); - offsIter += dynCount; - dynConsumed += dynCount; - RDCASSERT(dynConsumed <= offsCount); - } + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); - // if there are dynamic offsets, bake them into the current bindings by alias'ing - // the image layout member (which is never used for buffer views). - // This lets us look it up easily when we want to show the current pipeline state - RDCCOMPILE_ASSERT(sizeof(VkImageLayout) >= sizeof(uint32_t), - "Can't alias image layout for dynamic offset!"); - if(offsCount > 0) - { - uint32_t o = 0; + ObjDisp(commandBuffer) + ->CmdBindDescriptorSets(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), + firstSet, setCount, UnwrapArray(pDescriptorSets, setCount), + dynamicOffsetCount, pDynamicOffsets); - // spec states that dynamic offsets precisely match all the offsets needed for these - // sets, in order of set N before set N+1, binding X before binding X+1 within a set, - // and in array element order within a binding - for(uint32_t i = 0; i < numSets; i++) + std::vector &descsets = + (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) ? m_RenderState.graphics.descSets + : m_RenderState.compute.descSets; + + // expand as necessary + if(descsets.size() < firstSet + setCount) + descsets.resize(firstSet + setCount); + + const std::vector &descSetLayouts = + m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts; + + const uint32_t *offsIter = pDynamicOffsets; + uint32_t dynConsumed = 0; + + // consume the offsets linearly along the descriptor set layouts + for(uint32_t i = 0; i < setCount; i++) { - const DescSetLayout &layoutinfo = m_CreationInfo.m_DescSetLayout[descSetLayouts[first + i]]; + descsets[firstSet + i].descSet = GetResID(pDescriptorSets[i]); + uint32_t dynCount = + m_CreationInfo.m_DescSetLayout[descSetLayouts[firstSet + i]].dynamicCount; + descsets[firstSet + i].offsets.assign(offsIter, offsIter + dynCount); + offsIter += dynCount; + dynConsumed += dynCount; + RDCASSERT(dynConsumed <= dynamicOffsetCount); + } - for(size_t b = 0; b < layoutinfo.bindings.size(); b++) + // if there are dynamic offsets, bake them into the current bindings by alias'ing + // the image layout member (which is never used for buffer views). + // This lets us look it up easily when we want to show the current pipeline state + RDCCOMPILE_ASSERT(sizeof(VkImageLayout) >= sizeof(uint32_t), + "Can't alias image layout for dynamic offset!"); + if(dynamicOffsetCount > 0) + { + uint32_t o = 0; + + // spec states that dynamic offsets precisely match all the offsets needed for these + // sets, in order of set N before set N+1, binding X before binding X+1 within a set, + // and in array element order within a binding + for(uint32_t i = 0; i < setCount; i++) { - // not dynamic, doesn't need an offset - if(layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC && - layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - continue; + ResourceId descId = GetResID(pDescriptorSets[i]); + const DescSetLayout &layoutinfo = + m_CreationInfo.m_DescSetLayout[descSetLayouts[firstSet + i]]; - // assign every array element an offset according to array size - for(uint32_t a = 0; a < layoutinfo.bindings[b].descriptorCount; a++) + for(size_t b = 0; b < layoutinfo.bindings.size(); b++) { - RDCASSERT(o < offsCount); - uint32_t *alias = (uint32_t *)&m_DescriptorSetState[descriptorIDs[i]] - .currentBindings[b][a] - .imageInfo.imageLayout; - *alias = offs[o++]; + // not dynamic, doesn't need an offset + if(layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC && + layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) + continue; + + // assign every array element an offset according to array size + for(uint32_t a = 0; a < layoutinfo.bindings[b].descriptorCount; a++) + { + RDCASSERT(o < dynamicOffsetCount); + uint32_t *alias = + (uint32_t *)&m_DescriptorSetState[descId].currentBindings[b][a].imageInfo.imageLayout; + *alias = pDynamicOffsets[o++]; + } } } } } } + else + { + // track while reading, as we need to track resource usage + std::vector &descsets = + (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) + ? m_BakedCmdBufferInfo[m_LastCmdBufferID].state.graphicsDescSets + : m_BakedCmdBufferInfo[m_LastCmdBufferID].state.computeDescSets; + + // expand as necessary + if(descsets.size() < firstSet + setCount) + descsets.resize(firstSet + setCount); + + for(uint32_t i = 0; i < setCount; i++) + descsets[firstSet + i].descSet = GetResID(pDescriptorSets[i]); + + ObjDisp(commandBuffer) + ->CmdBindDescriptorSets(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), + firstSet, setCount, UnwrapArray(pDescriptorSets, setCount), + dynamicOffsetCount, pDynamicOffsets); + } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - layout = GetResourceManager()->GetLiveHandle(layoutid); - - // track while reading, as we need to track resource usage - vector &descsets = - (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - ? m_BakedCmdBufferInfo[m_LastCmdBufferID].state.graphicsDescSets - : m_BakedCmdBufferInfo[m_LastCmdBufferID].state.computeDescSets; - - // expand as necessary - if(descsets.size() < first + numSets) - descsets.resize(first + numSets); - - for(uint32_t i = 0; i < numSets; i++) - descsets[first + i].descSet = descriptorIDs[i]; - - ObjDisp(commandBuffer) - ->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, - offsCount, offs); - } - - if(m_State < WRITING) - { - SAFE_DELETE_ARRAY(sets); - SAFE_DELETE_ARRAY(descriptorIDs); - } - - SAFE_DELETE_ARRAY(offs); return true; } @@ -1425,24 +1390,20 @@ void WrappedVulkan::vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, { SCOPED_DBG_SINK(); - VkDescriptorSet *unwrapped = GetTempArray(setCount); - for(uint32_t i = 0; i < setCount; i++) - unwrapped[i] = Unwrap(pDescriptorSets[i]); - ObjDisp(commandBuffer) ->CmdBindDescriptorSets(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), firstSet, - setCount, unwrapped, dynamicOffsetCount, pDynamicOffsets); + setCount, UnwrapArray(pDescriptorSets, setCount), dynamicOffsetCount, + pDynamicOffsets); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_DESCRIPTOR_SET); - Serialise_vkCmdBindDescriptorSets(localSerialiser, commandBuffer, pipelineBindPoint, layout, - firstSet, setCount, pDescriptorSets, dynamicOffsetCount, - pDynamicOffsets); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindDescriptorSets); + Serialise_vkCmdBindDescriptorSets(ser, commandBuffer, pipelineBindPoint, layout, firstSet, + setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read); @@ -1469,78 +1430,58 @@ void WrappedVulkan::vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, } } -bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(Serialiser *localSerialiser, +template +bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(SerialiserType &ser, VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers, const VkDeviceSize *pOffsets) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, first, firstBinding); - SERIALISE_ELEMENT(uint32_t, count, bindingCount); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(firstBinding); + SERIALISE_ELEMENT_ARRAY(pBuffers, bindingCount); + SERIALISE_ELEMENT_ARRAY(pOffsets, bindingCount); + SERIALISE_ELEMENT(bindingCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - vector bufids; - vector bufs; - vector offs; - - for(uint32_t i = 0; i < count; i++) + if(IsReplayingAndReading()) { - ResourceId id; - VkDeviceSize o; - if(m_State >= WRITING) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - id = GetResID(pBuffers[i]); - o = pOffsets[i]; - } - - localSerialiser->Serialise("pBuffers[]", id); - localSerialiser->Serialise("pOffsets[]", o); - - if(m_State < WRITING) - { - VkBuffer buf = GetResourceManager()->GetLiveHandle(id); - bufids.push_back(GetResID(buf)); - bufs.push_back(Unwrap(buf)); - offs.push_back(o); - } - } - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer) - ->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); - - if(m_RenderState.vbuffers.size() < first + count) - m_RenderState.vbuffers.resize(first + count); - - for(uint32_t i = 0; i < count; i++) + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) { - m_RenderState.vbuffers[first + i].buf = bufids[i]; - m_RenderState.vbuffers[first + i].offs = offs[i]; + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + ObjDisp(commandBuffer) + ->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, + UnwrapArray(pBuffers, bindingCount), pOffsets); + + if(m_RenderState.vbuffers.size() < firstBinding + bindingCount) + m_RenderState.vbuffers.resize(firstBinding + bindingCount); + + for(uint32_t i = 0; i < bindingCount; i++) + { + m_RenderState.vbuffers[firstBinding + i].buf = GetResID(pBuffers[i]); + m_RenderState.vbuffers[firstBinding + i].offs = pOffsets[i]; + } } } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + else + { + // track while reading, as we need to track resource usage + if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.size() < firstBinding + bindingCount) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.resize(firstBinding + bindingCount); - // track while reading, as we need to track resource usage - if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.size() < first + count) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.resize(first + count); + for(uint32_t i = 0; i < bindingCount; i++) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers[firstBinding + i] = + GetResID(pBuffers[i]); - for(uint32_t i = 0; i < count; i++) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers[first + i] = bufids[i]; - - ObjDisp(commandBuffer) - ->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); + ObjDisp(commandBuffer) + ->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, + UnwrapArray(pBuffers, bindingCount), pOffsets); + } } return true; @@ -1552,22 +1493,19 @@ void WrappedVulkan::vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32 { SCOPED_DBG_SINK(); - VkBuffer *unwrapped = GetTempArray(bindingCount); - for(uint32_t i = 0; i < bindingCount; i++) - unwrapped[i] = Unwrap(pBuffers[i]); - ObjDisp(commandBuffer) - ->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, unwrapped, pOffsets); + ->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, + UnwrapArray(pBuffers, bindingCount), pOffsets); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_VERTEX_BUFFERS); - Serialise_vkCmdBindVertexBuffers(localSerialiser, commandBuffer, firstBinding, bindingCount, - pBuffers, pOffsets); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindVertexBuffers); + Serialise_vkCmdBindVertexBuffers(ser, commandBuffer, firstBinding, bindingCount, pBuffers, + pOffsets); record->AddChunk(scope.Get()); for(uint32_t i = 0; i < bindingCount; i++) @@ -1580,47 +1518,46 @@ void WrappedVulkan::vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32 } } -bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(Serialiser *localSerialiser, +template +bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(SerialiserType &ser, VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); - SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(VkIndexType, idxType, indexType); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(buffer); + SERIALISE_ELEMENT(offset); + SERIALISE_ELEMENT(indexType); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - buffer = GetResourceManager()->GetLiveHandle(bufid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + ObjDisp(commandBuffer) + ->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offset, indexType); - m_RenderState.ibuffer.buf = GetResID(buffer); - m_RenderState.ibuffer.offs = offs; - m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + m_RenderState.ibuffer.buf = GetResID(buffer); + m_RenderState.ibuffer.offs = offset; + m_RenderState.ibuffer.bytewidth = indexType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + } } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - buffer = GetResourceManager()->GetLiveHandle(bufid); + else + { + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = + (indexType == VK_INDEX_TYPE_UINT32 ? 4 : 2); - // track while reading, as we need to bind current topology & index byte width in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = - (idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2); + // track while reading, as we need to track resource usage + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer = GetResID(buffer); - // track while reading, as we need to track resource usage - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer = GetResID(buffer); - - ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); + ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offset, indexType); + } } return true; @@ -1633,14 +1570,14 @@ void WrappedVulkan::vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offset, indexType); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_INDEX_BUFFER); - Serialise_vkCmdBindIndexBuffer(localSerialiser, commandBuffer, buffer, offset, indexType); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBindIndexBuffer); + Serialise_vkCmdBindIndexBuffer(ser, commandBuffer, buffer, offset, indexType); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); @@ -1650,44 +1587,39 @@ void WrappedVulkan::vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer } } -bool WrappedVulkan::Serialise_vkCmdUpdateBuffer(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, VkBuffer destBuffer, - VkDeviceSize destOffset, VkDeviceSize dataSize, - const uint32_t *pData) +template +bool WrappedVulkan::Serialise_vkCmdUpdateBuffer(SerialiserType &ser, VkCommandBuffer commandBuffer, + VkBuffer destBuffer, VkDeviceSize destOffset, + VkDeviceSize dataSize, const uint32_t *pData) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, sz, dataSize); - SERIALISE_ELEMENT_BUF(byte *, bufdata, (byte *)pData, (size_t)dataSize); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(destBuffer); + SERIALISE_ELEMENT(destOffset); - Serialise_DebugMessages(localSerialiser, false); + // serialise as void* so it goes through as a buffer, not an actual array of integers. + const void *Data = (const void *)pData; + SERIALISE_ELEMENT_ARRAY(Data, dataSize); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(ser); - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) + { + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; + } + + if(commandBuffer != VK_NULL_HANDLE) { - commandBuffer = RerecordCmdBuf(cmdid); ObjDisp(commandBuffer) - ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); + ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, dataSize, Data); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); - - ObjDisp(commandBuffer) - ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); - } - - if(m_State < WRITING) - SAFE_DELETE_ARRAY(bufdata); return true; } @@ -1701,15 +1633,14 @@ void WrappedVulkan::vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer de ObjDisp(commandBuffer) ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, dataSize, pData); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(UPDATE_BUF); - Serialise_vkCmdUpdateBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, dataSize, - pData); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdUpdateBuffer); + Serialise_vkCmdUpdateBuffer(ser, commandBuffer, destBuffer, destOffset, dataSize, pData); record->AddChunk(scope.Get()); @@ -1725,38 +1656,36 @@ void WrappedVulkan::vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer de } } -bool WrappedVulkan::Serialise_vkCmdFillBuffer(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, VkBuffer destBuffer, - VkDeviceSize destOffset, VkDeviceSize fillSize, - uint32_t data) +template +bool WrappedVulkan::Serialise_vkCmdFillBuffer(SerialiserType &ser, VkCommandBuffer commandBuffer, + VkBuffer destBuffer, VkDeviceSize destOffset, + VkDeviceSize fillSize, uint32_t data) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, sz, fillSize); - SERIALISE_ELEMENT(uint32_t, d, data); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(destBuffer); + SERIALISE_ELEMENT(destOffset); + SERIALISE_ELEMENT(fillSize); + SERIALISE_ELEMENT(data); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); + if(commandBuffer != VK_NULL_HANDLE) + { + ObjDisp(commandBuffer) + ->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, fillSize, data); + } } return true; @@ -1770,14 +1699,14 @@ void WrappedVulkan::vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dest ObjDisp(commandBuffer) ->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, fillSize, data); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(FILL_BUF); - Serialise_vkCmdFillBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, fillSize, data); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdFillBuffer); + Serialise_vkCmdFillBuffer(ser, commandBuffer, destBuffer, destOffset, fillSize, data); record->AddChunk(scope.Get()); @@ -1793,47 +1722,46 @@ void WrappedVulkan::vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dest } } -bool WrappedVulkan::Serialise_vkCmdPushConstants(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdPushConstants(SerialiserType &ser, VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t start, uint32_t length, const void *values) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, layid, GetResID(layout)); - SERIALISE_ELEMENT(VkShaderStageFlagBits, flags, (VkShaderStageFlagBits)stageFlags); - SERIALISE_ELEMENT(uint32_t, s, start); - SERIALISE_ELEMENT(uint32_t, len, length); - SERIALISE_ELEMENT_BUF(byte *, vals, (byte *)values, (size_t)len); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(layout); + SERIALISE_ELEMENT_TYPED(VkShaderStageFlagBits, stageFlags); + SERIALISE_ELEMENT(start); + SERIALISE_ELEMENT_ARRAY(values, length); + SERIALISE_ELEMENT(length); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - layout = GetResourceManager()->GetLiveHandle(layid); - ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + ObjDisp(commandBuffer) + ->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), stageFlags, start, length, + values); - RDCASSERT(s + len < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts)); + RDCASSERT(start + length < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts)); - memcpy(m_RenderState.pushconsts + s, vals, len); + memcpy(m_RenderState.pushconsts + start, values, length); + } + } + else + { + ObjDisp(commandBuffer) + ->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), stageFlags, start, length, + values); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - layout = GetResourceManager()->GetLiveHandle(layid); - - ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); - } - - if(m_State < WRITING) - SAFE_DELETE_ARRAY(vals); return true; } @@ -1847,65 +1775,65 @@ void WrappedVulkan::vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipeline ObjDisp(commandBuffer) ->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), stageFlags, start, length, values); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(PUSH_CONST); - Serialise_vkCmdPushConstants(localSerialiser, commandBuffer, layout, stageFlags, start, length, - values); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdPushConstants); + Serialise_vkCmdPushConstants(ser, commandBuffer, layout, stageFlags, start, length, values); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read); } } +template bool WrappedVulkan::Serialise_vkCmdPipelineBarrier( - Serialiser *localSerialiser, VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, + SerialiserType &ser, VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)destStageMask); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_TYPED(VkPipelineStageFlagBits, srcStageMask); + SERIALISE_ELEMENT_TYPED(VkPipelineStageFlagBits, destStageMask); + SERIALISE_ELEMENT_TYPED(VkDependencyFlagBits, dependencyFlags); + SERIALISE_ELEMENT_ARRAY(pMemoryBarriers, memoryBarrierCount); + SERIALISE_ELEMENT_ARRAY(pBufferMemoryBarriers, bufferMemoryBarrierCount); + SERIALISE_ELEMENT_ARRAY(pImageMemoryBarriers, imageMemoryBarrierCount); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(ser); - SERIALISE_ELEMENT(VkDependencyFlags, flags, dependencyFlags); - - SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount); - - SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount); - SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount); - SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount); - - Serialise_DebugMessages(localSerialiser, false); - - vector imgBarriers; - vector bufBarriers; + std::vector imgBarriers; + std::vector bufBarriers; // it's possible for buffer or image to be NULL if it refers to a resource that is otherwise // not in the log (barriers do not mark resources referenced). If the resource in question does // not exist, then it's safe to skip this barrier. - - if(m_State < WRITING) + // + // Since it's a convenient place, we unwrap at the same time. + if(IsReplayingAndReading()) { - for(uint32_t i = 0; i < bufCount; i++) - if(bufMemBarriers[i].buffer != VK_NULL_HANDLE) - bufBarriers.push_back(bufMemBarriers[i]); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - for(uint32_t i = 0; i < imgCount; i++) + for(uint32_t i = 0; i < bufferMemoryBarrierCount; i++) { - if(imgMemBarriers[i].image != VK_NULL_HANDLE) + if(pBufferMemoryBarriers[i].buffer != VK_NULL_HANDLE) { - imgBarriers.push_back(imgMemBarriers[i]); + bufBarriers.push_back(pBufferMemoryBarriers[i]); + bufBarriers.back().buffer = Unwrap(bufBarriers.back().buffer); + } + } + + for(uint32_t i = 0; i < imageMemoryBarrierCount; i++) + { + if(pImageMemoryBarriers[i].image != VK_NULL_HANDLE) + { + imgBarriers.push_back(pImageMemoryBarriers[i]); + imgBarriers.back().image = Unwrap(imgBarriers.back().image); ReplacePresentableImageLayout(imgBarriers.back().oldLayout); ReplacePresentableImageLayout(imgBarriers.back().newLayout); @@ -1913,50 +1841,38 @@ bool WrappedVulkan::Serialise_vkCmdPipelineBarrier( imgBarriers.back().dstQueueFamilyIndex); } } - } - SAFE_DELETE_ARRAY(bufMemBarriers); - SAFE_DELETE_ARRAY(imgMemBarriers); - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) + { + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; + } + else + { + ResourceId cmd = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + for(size_t i = 0; i < imgBarriers.size(); i++) + { + m_BakedCmdBufferInfo[cmd].resourceUsage.push_back(std::make_pair( + GetResID(imgBarriers[i].image), + EventUsage(m_BakedCmdBufferInfo[cmd].curEventID, ResourceUsage::Barrier))); + } + } + + if(commandBuffer != VK_NULL_HANDLE) { - commandBuffer = RerecordCmdBuf(cmdid); ObjDisp(commandBuffer) - ->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, - (VkPipelineStageFlags)destStages, flags, memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + ->CmdPipelineBarrier(Unwrap(commandBuffer), srcStageMask, destStageMask, dependencyFlags, + memoryBarrierCount, pMemoryBarriers, (uint32_t)bufBarriers.size(), + bufBarriers.data(), (uint32_t)imgBarriers.size(), imgBarriers.data()); ResourceId cmd = GetResID(commandBuffer); GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + (uint32_t)imgBarriers.size(), imgBarriers.data()); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - ObjDisp(commandBuffer) - ->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, - (VkPipelineStageFlags)destStages, flags, memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - ResourceId cmd = GetResID(commandBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - for(size_t i = 0; i < imgBarriers.size(); i++) - { - m_BakedCmdBufferInfo[cmdid].resourceUsage.push_back(std::make_pair( - GetResourceManager()->GetNonDispWrapper(imgBarriers[i].image)->id, - EventUsage(m_BakedCmdBufferInfo[cmdid].curEventID, ResourceUsage::Barrier))); - } - } - - SAFE_DELETE_ARRAY(memBarriers); return true; } @@ -1995,17 +1911,17 @@ void WrappedVulkan::vkCmdPipelineBarrier( imageMemoryBarrierCount, im); } - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(PIPELINE_BARRIER); - Serialise_vkCmdPipelineBarrier(localSerialiser, commandBuffer, srcStageMask, destStageMask, - dependencyFlags, memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, pBufferMemoryBarriers, - imageMemoryBarrierCount, pImageMemoryBarriers); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdPipelineBarrier); + Serialise_vkCmdPipelineBarrier(ser, commandBuffer, srcStageMask, destStageMask, dependencyFlags, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, + pBufferMemoryBarriers, imageMemoryBarrierCount, + pImageMemoryBarriers); record->AddChunk(scope.Get()); @@ -2019,37 +1935,35 @@ void WrappedVulkan::vkCmdPipelineBarrier( } } -bool WrappedVulkan::Serialise_vkCmdWriteTimestamp(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdWriteTimestamp(SerialiserType &ser, VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, stage, pipelineStage); - SERIALISE_ELEMENT(ResourceId, poolid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(pipelineStage); + SERIALISE_ELEMENT(queryPool); + SERIALISE_ELEMENT(query); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - queryPool = GetResourceManager()->GetLiveHandle(poolid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(poolid); - ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); + if(commandBuffer != VK_NULL_HANDLE) + { + ObjDisp(commandBuffer) + ->CmdWriteTimestamp(Unwrap(commandBuffer), pipelineStage, Unwrap(queryPool), query); + } } return true; @@ -2064,14 +1978,14 @@ void WrappedVulkan::vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, ObjDisp(commandBuffer) ->CmdWriteTimestamp(Unwrap(commandBuffer), pipelineStage, Unwrap(queryPool), query); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(WRITE_TIMESTAMP); - Serialise_vkCmdWriteTimestamp(localSerialiser, commandBuffer, pipelineStage, queryPool, query); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdWriteTimestamp); + Serialise_vkCmdWriteTimestamp(ser, commandBuffer, pipelineStage, queryPool, query); record->AddChunk(scope.Get()); @@ -2079,47 +1993,41 @@ void WrappedVulkan::vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, } } +template bool WrappedVulkan::Serialise_vkCmdCopyQueryPoolResults( - Serialiser *localSerialiser, VkCommandBuffer commandBuffer, VkQueryPool queryPool, - uint32_t firstQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, - VkDeviceSize destStride, VkQueryResultFlags flags) + SerialiserType &ser, VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, + uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, + VkQueryResultFlags flags) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, first, firstQuery); - SERIALISE_ELEMENT(uint32_t, count, queryCount); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, stride, destStride); - SERIALISE_ELEMENT(VkQueryResultFlagBits, f, (VkQueryResultFlagBits)flags); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(queryPool); + SERIALISE_ELEMENT(firstQuery); + SERIALISE_ELEMENT(queryCount); + SERIALISE_ELEMENT(destBuffer); + SERIALISE_ELEMENT(destOffset); + SERIALISE_ELEMENT(destStride); + SERIALISE_ELEMENT_TYPED(VkQueryResultFlagBits, flags); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - queryPool = GetResourceManager()->GetLiveHandle(qid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer) - ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, - Unwrap(destBuffer), offs, stride, f); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer) - ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, - Unwrap(destBuffer), offs, stride, f); + if(commandBuffer != VK_NULL_HANDLE) + { + ObjDisp(commandBuffer) + ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, + queryCount, Unwrap(destBuffer), destOffset, destStride, flags); + } } return true; @@ -2136,15 +2044,15 @@ void WrappedVulkan::vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQ ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount, Unwrap(destBuffer), destOffset, destStride, flags); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(COPY_QUERY_RESULTS); - Serialise_vkCmdCopyQueryPoolResults(localSerialiser, commandBuffer, queryPool, firstQuery, - queryCount, destBuffer, destOffset, destStride, flags); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdCopyQueryPoolResults); + Serialise_vkCmdCopyQueryPoolResults(ser, commandBuffer, queryPool, firstQuery, queryCount, + destBuffer, destOffset, destStride, flags); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); @@ -2161,38 +2069,32 @@ void WrappedVulkan::vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQ } } -bool WrappedVulkan::Serialise_vkCmdBeginQuery(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, VkQueryPool queryPool, - uint32_t query, VkQueryControlFlags flags) +template +bool WrappedVulkan::Serialise_vkCmdBeginQuery(SerialiserType &ser, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query, + VkQueryControlFlags flags) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); - SERIALISE_ELEMENT( - VkQueryControlFlagBits, f, - (VkQueryControlFlagBits)flags); // serialise as 'bits' type to get nice enum values + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(queryPool); + SERIALISE_ELEMENT(query); + SERIALISE_ELEMENT_TYPED(VkQueryControlFlagBits, flags); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - queryPool = GetResourceManager()->GetLiveHandle(qid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); + if(commandBuffer != VK_NULL_HANDLE) + ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), query, flags); } return true; @@ -2205,49 +2107,44 @@ void WrappedVulkan::vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool q ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), query, flags); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY); - Serialise_vkCmdBeginQuery(localSerialiser, commandBuffer, queryPool, query, flags); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginQuery); + Serialise_vkCmdBeginQuery(ser, commandBuffer, queryPool, query, flags); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); } } -bool WrappedVulkan::Serialise_vkCmdEndQuery(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, VkQueryPool queryPool, - uint32_t query) +template +bool WrappedVulkan::Serialise_vkCmdEndQuery(SerialiserType &ser, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(queryPool); + SERIALISE_ELEMENT(query); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - queryPool = GetResourceManager()->GetLiveHandle(qid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); + if(commandBuffer != VK_NULL_HANDLE) + ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), query); } return true; @@ -2259,51 +2156,49 @@ void WrappedVulkan::vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool que ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), query); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(END_QUERY); - Serialise_vkCmdEndQuery(localSerialiser, commandBuffer, queryPool, query); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndQuery); + Serialise_vkCmdEndQuery(ser, commandBuffer, queryPool, query); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); } } -bool WrappedVulkan::Serialise_vkCmdResetQueryPool(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdResetQueryPool(SerialiserType &ser, VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, first, firstQuery); - SERIALISE_ELEMENT(uint32_t, count, queryCount); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT(queryPool); + SERIALISE_ELEMENT(firstQuery); + SERIALISE_ELEMENT(queryCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - queryPool = GetResourceManager()->GetLiveHandle(qid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + else + commandBuffer = VK_NULL_HANDLE; } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); + if(commandBuffer != VK_NULL_HANDLE) + { + ObjDisp(commandBuffer) + ->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount); + } } return true; @@ -2317,294 +2212,276 @@ void WrappedVulkan::vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPo ObjDisp(commandBuffer) ->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(RESET_QUERY_POOL); - Serialise_vkCmdResetQueryPool(localSerialiser, commandBuffer, queryPool, firstQuery, queryCount); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdResetQueryPool); + Serialise_vkCmdResetQueryPool(ser, commandBuffer, queryPool, firstQuery, queryCount); record->AddChunk(scope.Get()); record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); } } -bool WrappedVulkan::Serialise_vkCmdExecuteCommands(Serialiser *localSerialiser, - VkCommandBuffer commandBuffer, +template +bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkCommandBuffer commandBuffer, uint32_t commandBufferCount, - const VkCommandBuffer *pCmdBuffers) + const VkCommandBuffer *pCommandBuffers) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, count, commandBufferCount); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_ARRAY(pCommandBuffers, commandBufferCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(ser); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - vector cmdids; - vector cmds; - - for(uint32_t i = 0; i < count; i++) + if(IsReplayingAndReading()) { - ResourceId id; - if(m_State >= WRITING) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsLoading(m_State)) { - VkResourceRecord *bakedCommands = GetRecord(pCmdBuffers[i])->bakedCommands; - if(bakedCommands) - id = bakedCommands->GetResourceID(); - else - RDCERR("Command Buffer %p was not recorded", pCmdBuffers[i]); - } + // execute the commands + ObjDisp(commandBuffer) + ->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, + UnwrapArray(pCommandBuffers, commandBufferCount)); - localSerialiser->Serialise("pCmdBuffers[]", id); + // apply barriers + for(uint32_t i = 0; i < commandBufferCount; i++) + GetResourceManager()->ApplyBarriers( + m_BakedCmdBufferInfo[GetResID(pCommandBuffers[i])].imgbarriers, m_ImageLayouts); - if(m_State < WRITING && id != ResourceId()) - { - cmdids.push_back(id); - cmds.push_back(Unwrap(GetResourceManager()->GetLiveHandle(id))); - } - } + AddEvent(); - if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + DrawcallDescription draw; + draw.name = StringFormat::Fmt("vkCmdExecuteCommands(%u)", commandBufferCount); + draw.flags = DrawFlags::CmdList | DrawFlags::PushMarker; - // execute the commands - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); - - // apply barriers - for(uint32_t i = 0; i < count; i++) - { - ResourceId cmd = GetResourceManager()->GetLiveID(cmdids[i]); - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); - } - - const string desc = localSerialiser->GetDebugStr(); - - AddEvent(desc); - - DrawcallDescription draw; - draw.name = "vkCmdExecuteCommands(" + ToStr(count) + ")"; - draw.flags = DrawFlags::CmdList | DrawFlags::PushMarker; - - AddDrawcall(draw, true); - - BakedCmdBufferInfo &parentCmdBufInfo = m_BakedCmdBufferInfo[m_LastCmdBufferID]; - - parentCmdBufInfo.curEventID++; - - for(uint32_t c = 0; c < count; c++) - { - string name = StringFormat::Fmt("=> vkCmdExecuteCommands()[%u]: vkBeginCommandBuffer(%s)", c, - ToStr(cmdids[c]).c_str()); - - // add a fake marker - DrawcallDescription marker; - marker.name = name; - marker.flags = DrawFlags::PassBoundary | DrawFlags::BeginPass; - AddEvent(name); - AddDrawcall(marker, true); - parentCmdBufInfo.curEventID++; - - BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmdids[c]]; - - if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass == ResourceId() && - (cmdBufInfo.beginFlags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) - { - AddDebugMessage( - MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, - "Executing a command buffer with RENDER_PASS_CONTINUE_BIT outside of render pass"); - } - - // insert the baked command buffer in-line into this list of notes, assigning new event and - // drawIDs - parentCmdBufInfo.draw->InsertAndUpdateIDs(*cmdBufInfo.draw, parentCmdBufInfo.curEventID, - parentCmdBufInfo.drawCount); - - for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++) - { - parentCmdBufInfo.debugMessages.push_back(cmdBufInfo.debugMessages[i]); - parentCmdBufInfo.debugMessages.back().eventID += parentCmdBufInfo.curEventID; - } - - // only primary command buffers can be submitted - m_Partial[Secondary].cmdBufferSubmits[cmdids[c]].push_back(parentCmdBufInfo.curEventID); - - parentCmdBufInfo.draw->executedCmds.push_back(cmdids[c]); - - parentCmdBufInfo.curEventID += cmdBufInfo.eventCount; - parentCmdBufInfo.drawCount += cmdBufInfo.drawCount; - - name = StringFormat::Fmt("=> vkCmdExecuteCommands()[%u]: vkEndCommandBuffer(%s)", c, - ToStr(cmdids[c]).c_str()); - marker.name = name; - marker.flags = DrawFlags::PassBoundary | DrawFlags::EndPass; - AddEvent(name); - AddDrawcall(marker, true); - parentCmdBufInfo.curEventID++; - } - - // add an extra pop marker - draw = DrawcallDescription(); - draw.flags = DrawFlags::PopMarker; - - AddDrawcall(draw, true); - - // don't change curEventID here, as it will be incremented outside in the outer - // loop for the EXEC_CMDS event. in vkQueueSubmit we need to decrement curEventID - // because we don't have the extra popmarker event to 'absorb' the outer loop's - // increment, and it incremented once too many for the last vkEndCommandBuffer - // setmarker event in the loop over all commands - } - else if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); + AddDrawcall(draw, true); BakedCmdBufferInfo &parentCmdBufInfo = m_BakedCmdBufferInfo[m_LastCmdBufferID]; - // if we're replaying a range but not from the start, we are guaranteed to only be replaying - // one of our executed command buffers and doing it to an outside command buffer. The outer - // loop will be doing SetOffset() to jump to each event, and any time we land here is just for - // the markers we've added, which have this file offset, so just skip all of our work. - if(m_FirstEventID > 1 && m_FirstEventID + 1 < m_LastEventID) - return true; - - // account for the execute commands event parentCmdBufInfo.curEventID++; - uint32_t startEID = parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent; - - // advance m_CurEventID to match the events added when reading - for(uint32_t c = 0; c < count; c++) + for(uint32_t c = 0; c < commandBufferCount; c++) { - // 2 extra for the virtual labels around the command buffer - parentCmdBufInfo.curEventID += 2 + m_BakedCmdBufferInfo[cmdids[c]].eventCount; - } + ResourceId cmd = GetResourceManager()->GetOriginalID(GetResID(pCommandBuffers[c])); - // same accounting for the outer loop as above means no need to change anything here + // add a fake marker + DrawcallDescription marker; + marker.name = StringFormat::Fmt("=> vkCmdExecuteCommands()[%u]: vkBeginCommandBuffer(%s)", + c, ToStr(cmd).c_str()); + marker.flags = DrawFlags::PassBoundary | DrawFlags::BeginPass; + AddEvent(); + AddDrawcall(marker, true); + parentCmdBufInfo.curEventID++; - if(count == 0) - { - // do nothing, don't bother with the logic below - } - else if(m_FirstEventID == m_LastEventID) - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands no OnlyDraw %u", m_FirstEventID); -#endif - } - else if(m_LastEventID <= startEID) - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands no replay %u == %u", m_LastEventID, startEID); -#endif - } - else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands re-recording from %u", startEID); -#endif + BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmd]; - vector rerecordedCmds; - - for(uint32_t c = 0; c < count; c++) + if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass == ResourceId() && + (cmdBufInfo.beginFlags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { - VkCommandBuffer cmd = RerecordCmdBuf(cmdids[c]); - ResourceId rerecord = GetResID(cmd); -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands fully re-recorded replay of %llu, using %llu", cmdids[c], - rerecord); -#endif - rerecordedCmds.push_back(Unwrap(cmd)); - - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers, - m_ImageLayouts); + AddDebugMessage( + MessageCategory::Execution, MessageSeverity::High, MessageSource::IncorrectAPIUse, + "Executing a command buffer with RENDER_PASS_CONTINUE_BIT outside of render pass"); } - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &rerecordedCmds[0]); - } - else if(m_LastEventID > startEID && - m_LastEventID < parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent) - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands partial replay %u < %u", m_LastEventID, - parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent); -#endif + // insert the baked command buffer in-line into this list of notes, assigning new event and + // drawIDs + parentCmdBufInfo.draw->InsertAndUpdateIDs(*cmdBufInfo.draw, parentCmdBufInfo.curEventID, + parentCmdBufInfo.drawCount); - uint32_t eid = startEID; - - vector trimmedCmdIds; - vector trimmedCmds; - - for(uint32_t c = 0; c < count; c++) + for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++) { - // account for the virtual vkBeginCommandBuffer label at the start of the events here - // so it matches up to baseEvent - eid++; - - uint32_t end = eid + m_BakedCmdBufferInfo[cmdids[c]].eventCount; - - if(eid == m_Partial[Secondary].baseEvent) - { - ResourceId partial = GetResID(RerecordCmdBuf(cmdids[c], Secondary)); -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands partial replay of %llu at %u, using %llu", cmdids[c], eid, - partial); -#endif - trimmedCmdIds.push_back(partial); - trimmedCmds.push_back(Unwrap(RerecordCmdBuf(cmdids[c], Secondary))); - } - else if(m_LastEventID >= end) - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands full replay %llu", cmdids[c]); -#endif - trimmedCmdIds.push_back(cmdids[c]); - trimmedCmds.push_back( - Unwrap(GetResourceManager()->GetLiveHandle(cmdids[c]))); - } - else - { -#if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("not executing %llu", cmdids[c]); -#endif - } - - // 1 extra to account for the virtual end command buffer label (begin is accounted for - // above) - eid += 1 + m_BakedCmdBufferInfo[cmdids[c]].eventCount; + parentCmdBufInfo.debugMessages.push_back(cmdBufInfo.debugMessages[i]); + parentCmdBufInfo.debugMessages.back().eventID += parentCmdBufInfo.curEventID; } - if(trimmedCmds.size() > 0) + // only primary command buffers can be submitted + m_Partial[Secondary].cmdBufferSubmits[cmd].push_back(parentCmdBufInfo.curEventID); + + parentCmdBufInfo.draw->executedCmds.push_back(cmd); + + parentCmdBufInfo.curEventID += cmdBufInfo.eventCount; + parentCmdBufInfo.drawCount += cmdBufInfo.drawCount; + + marker.name = StringFormat::Fmt("=> vkCmdExecuteCommands()[%u]: vkEndCommandBuffer(%s)", c, + ToStr(cmd).c_str()); + marker.flags = DrawFlags::PassBoundary | DrawFlags::EndPass; + AddEvent(); + AddDrawcall(marker, true); + parentCmdBufInfo.curEventID++; + } + + // add an extra pop marker + draw = DrawcallDescription(); + draw.flags = DrawFlags::PopMarker; + + AddDrawcall(draw, true); + + // don't change curEventID here, as it will be incremented outside in the outer + // loop for the EXEC_CMDS event. in vkQueueSubmit we need to decrement curEventID + // because we don't have the extra popmarker event to 'absorb' the outer loop's + // increment, and it incremented once too many for the last vkEndCommandBuffer + // setmarker event in the loop over all commands + } + else + { + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + BakedCmdBufferInfo &parentCmdBufInfo = m_BakedCmdBufferInfo[m_LastCmdBufferID]; + + // if we're replaying a range but not from the start, we are guaranteed to only be replaying + // one of our executed command buffers and doing it to an outside command buffer. The outer + // loop will be doing SetOffset() to jump to each event, and any time we land here is just + // for + // the markers we've added, which have this file offset, so just skip all of our work. + if(m_FirstEventID > 1 && m_FirstEventID + 1 < m_LastEventID) + return true; + + // account for the execute commands event + parentCmdBufInfo.curEventID++; + + uint32_t startEID = parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent; + + // advance m_CurEventID to match the events added when reading + for(uint32_t c = 0; c < commandBufferCount; c++) + { + ResourceId cmd = GetResourceManager()->GetOriginalID(GetResID(pCommandBuffers[c])); + + // 2 extra for the virtual labels around the command buffer + parentCmdBufInfo.curEventID += 2 + m_BakedCmdBufferInfo[cmd].eventCount; + } + + // same accounting for the outer loop as above means no need to change anything here + + if(commandBufferCount == 0) + { + // do nothing, don't bother with the logic below + } + else if(m_FirstEventID == m_LastEventID) + { +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands no OnlyDraw %u", m_FirstEventID); +#endif + } + else if(m_LastEventID <= startEID) + { +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands no replay %u == %u", m_LastEventID, startEID); +#endif + } + else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) + { +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands re-recording from %u", startEID); +#endif + + std::vector rerecordedCmds; + + for(uint32_t c = 0; c < commandBufferCount; c++) + { + ResourceId cmdid = GetResourceManager()->GetOriginalID(GetResID(pCommandBuffers[c])); + VkCommandBuffer cmd = RerecordCmdBuf(cmdid); + ResourceId rerecord = GetResID(cmd); +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands fully re-recorded replay of %llu, using %llu", cmdid, rerecord); +#endif + rerecordedCmds.push_back(Unwrap(cmd)); + + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers, + m_ImageLayouts); + } + ObjDisp(commandBuffer) - ->CmdExecuteCommands(Unwrap(commandBuffer), (uint32_t)trimmedCmds.size(), - &trimmedCmds[0]); - - for(uint32_t i = 0; i < trimmedCmdIds.size(); i++) - { - ResourceId cmd = trimmedCmdIds[i]; - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); + ->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, &rerecordedCmds[0]); } - } - else - { + else if(m_LastEventID > startEID && + m_LastEventID < parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent) + { #if ENABLED(VERBOSE_PARTIAL_REPLAY) - RDCDEBUG("ExecuteCommands full replay %u >= %u", m_LastEventID, - parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent); + RDCDEBUG("ExecuteCommands partial replay %u < %u", m_LastEventID, + parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent); #endif - // execute the commands - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); + uint32_t eid = startEID; - for(uint32_t i = 0; i < count; i++) + std::vector trimmedCmdIds; + std::vector trimmedCmds; + + for(uint32_t c = 0; c < commandBufferCount; c++) + { + ResourceId cmdid = GetResourceManager()->GetOriginalID(GetResID(pCommandBuffers[c])); + + // account for the virtual vkBeginCommandBuffer label at the start of the events here + // so it matches up to baseEvent + eid++; + + uint32_t end = eid + m_BakedCmdBufferInfo[cmdid].eventCount; + + if(eid == m_Partial[Secondary].baseEvent) + { + ResourceId partial = GetResID(RerecordCmdBuf(cmdid, Secondary)); +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands partial replay of %llu at %u, using %llu", cmdid, eid, + partial); +#endif + trimmedCmdIds.push_back(partial); + trimmedCmds.push_back(Unwrap(RerecordCmdBuf(cmdid, Secondary))); + } + else if(m_LastEventID >= end) + { +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands full replay %llu", cmdid); +#endif + trimmedCmdIds.push_back(cmdid); + trimmedCmds.push_back( + Unwrap(GetResourceManager()->GetLiveHandle(cmdid))); + } + else + { +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("not executing %llu", cmdid); +#endif + } + + // 1 extra to account for the virtual end command buffer label (begin is accounted for + // above) + eid += 1 + m_BakedCmdBufferInfo[cmdid].eventCount; + } + + if(trimmedCmds.size() > 0) + ObjDisp(commandBuffer) + ->CmdExecuteCommands(Unwrap(commandBuffer), (uint32_t)trimmedCmds.size(), + &trimmedCmds[0]); + + for(uint32_t i = 0; i < trimmedCmdIds.size(); i++) + { + ResourceId cmd = trimmedCmdIds[i]; + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, + m_ImageLayouts); + } + } + else { - ResourceId cmd = GetResourceManager()->GetLiveID(cmdids[i]); - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); +#if ENABLED(VERBOSE_PARTIAL_REPLAY) + RDCDEBUG("ExecuteCommands full replay %u >= %u", m_LastEventID, + parentCmdBufInfo.curEventID + m_Partial[Primary].baseEvent); +#endif + + // execute the commands + ObjDisp(commandBuffer) + ->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, + UnwrapArray(pCommandBuffers, commandBufferCount)); + + for(uint32_t i = 0; i < commandBufferCount; i++) + { + GetResourceManager()->ApplyBarriers( + m_BakedCmdBufferInfo[GetResID(pCommandBuffers[i])].imgbarriers, m_ImageLayouts); + } } } } @@ -2614,29 +2491,28 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(Serialiser *localSerialiser, } void WrappedVulkan::vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, - const VkCommandBuffer *pCmdBuffers) + const VkCommandBuffer *pCommandBuffers) { SCOPED_DBG_SINK(); - VkCommandBuffer *unwrapped = GetTempArray(commandBufferCount); - for(uint32_t i = 0; i < commandBufferCount; i++) - unwrapped[i] = Unwrap(pCmdBuffers[i]); - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, unwrapped); + ObjDisp(commandBuffer) + ->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, + UnwrapArray(pCommandBuffers, commandBufferCount)); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(EXEC_CMDS); - Serialise_vkCmdExecuteCommands(localSerialiser, commandBuffer, commandBufferCount, pCmdBuffers); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdExecuteCommands); + Serialise_vkCmdExecuteCommands(ser, commandBuffer, commandBufferCount, pCommandBuffers); record->AddChunk(scope.Get()); for(uint32_t i = 0; i < commandBufferCount; i++) { - VkResourceRecord *execRecord = GetRecord(pCmdBuffers[i]); + VkResourceRecord *execRecord = GetRecord(pCommandBuffers[i]); if(execRecord->bakedCommands) { record->cmdInfo->dirtied.insert(execRecord->bakedCommands->cmdInfo->dirtied.begin(), @@ -2653,64 +2529,46 @@ void WrappedVulkan::vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerBeginEXT(Serialiser *localSerialiser, +template +bool WrappedVulkan::Serialise_vkCmdDebugMarkerBeginEXT(SerialiserType &ser, VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT *pMarker) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(string, name, - pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_LOCAL(Marker, *pMarker); - float color[4] = {}; - if(m_State >= WRITING && pMarker) - memcpy(color, pMarker->color, sizeof(color)); - - localSerialiser->SerialisePODArray<4>("color", color); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); - - m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount++; - - if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) { - VkDebugMarkerMarkerInfoEXT marker = {}; - marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; - memcpy(marker.color, color, sizeof(color)); - marker.pMarkerName = name.c_str(); - ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &marker); + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount++; + + if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &Marker); } } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) + else { - VkDebugMarkerMarkerInfoEXT marker = {}; - marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; - memcpy(marker.color, color, sizeof(color)); - marker.pMarkerName = name.c_str(); - ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &marker); + if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), &Marker); + + DrawcallDescription draw; + draw.name = Marker.pMarkerName; + draw.flags |= DrawFlags::PushMarker; + + draw.markerColor[0] = RDCCLAMP(Marker.color[0], 0.0f, 1.0f); + draw.markerColor[1] = RDCCLAMP(Marker.color[1], 0.0f, 1.0f); + draw.markerColor[2] = RDCCLAMP(Marker.color[2], 0.0f, 1.0f); + draw.markerColor[3] = RDCCLAMP(Marker.color[3], 0.0f, 1.0f); + + AddDrawcall(draw, false); } - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::PushMarker; - - draw.markerColor[0] = RDCCLAMP(color[0], 0.0f, 1.0f); - draw.markerColor[1] = RDCCLAMP(color[1], 0.0f, 1.0f); - draw.markerColor[2] = RDCCLAMP(color[2], 0.0f, 1.0f); - draw.markerColor[3] = RDCCLAMP(color[3], 0.0f, 1.0f); - - AddDrawcall(draw, false); } return true; @@ -2722,64 +2580,65 @@ void WrappedVulkan::vkCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), pMarker); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_vkCmdDebugMarkerBeginEXT(localSerialiser, commandBuffer, pMarker); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerBeginEXT); + Serialise_vkCmdDebugMarkerBeginEXT(ser, commandBuffer, pMarker); record->AddChunk(scope.Get()); } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerEndEXT(Serialiser *localSerialiser, +template +bool WrappedVulkan::Serialise_vkCmdDebugMarkerEndEXT(SerialiserType &ser, VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(commandBuffer); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) + if(IsReplayingAndReading()) { - DrawcallDescription draw; - draw.name = "API Calls"; - draw.flags = DrawFlags::SetMarker | DrawFlags::APICalls; + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - AddDrawcall(draw, true); - } - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) + if(IsActiveReplaying(m_State)) { - commandBuffer = RerecordCmdBuf(cmdid); + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); - int &markerCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount; - markerCount = RDCMAX(0, markerCount - 1); + int &markerCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].markerCount; + markerCount = RDCMAX(0, markerCount - 1); + if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); + } + } + else + { if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); + + if(!m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) + { + DrawcallDescription draw; + draw.name = "API Calls"; + draw.flags = DrawFlags::SetMarker | DrawFlags::APICalls; + + AddDrawcall(draw, true); + } + + // dummy draw that is consumed when this command buffer + // is being in-lined into the call stream + DrawcallDescription draw; + draw.name = "Pop()"; + draw.flags = DrawFlags::PopMarker; + + AddDrawcall(draw, false); } } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) - ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); - - // dummy draw that is consumed when this command buffer - // is being in-lined into the call stream - DrawcallDescription draw; - draw.name = "Pop()"; - draw.flags = DrawFlags::PopMarker; - - AddDrawcall(draw, false); - } return true; } @@ -2789,75 +2648,57 @@ void WrappedVulkan::vkCmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_vkCmdDebugMarkerEndEXT(localSerialiser, commandBuffer); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerEndEXT); + Serialise_vkCmdDebugMarkerEndEXT(ser, commandBuffer); record->AddChunk(scope.Get()); } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerInsertEXT(Serialiser *localSerialiser, +template +bool WrappedVulkan::Serialise_vkCmdDebugMarkerInsertEXT(SerialiserType &ser, VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT *pMarker) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(string, name, - pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_LOCAL(Marker, *pMarker); - float color[4] = {}; - if(m_State >= WRITING && pMarker) - memcpy(color, pMarker->color, sizeof(color)); - - localSerialiser->SerialisePODArray<4>("color", color); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) + if(IsReplayingAndReading()) { - if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); - if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) + if(IsActiveReplaying(m_State)) + { + if(ShouldRerecordCmd(m_LastCmdBufferID) && InRerecordRange(m_LastCmdBufferID)) { - VkDebugMarkerMarkerInfoEXT marker = {}; - marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; - memcpy(marker.color, color, sizeof(color)); - marker.pMarkerName = name.c_str(); - ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &marker); + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &Marker); } } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) + else { - VkDebugMarkerMarkerInfoEXT marker = {}; - marker.sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT; - memcpy(marker.color, color, sizeof(color)); - marker.pMarkerName = name.c_str(); - ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &marker); + if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), &Marker); + + DrawcallDescription draw; + draw.name = Marker.pMarkerName; + draw.flags |= DrawFlags::SetMarker; + + draw.markerColor[0] = RDCCLAMP(Marker.color[0], 0.0f, 1.0f); + draw.markerColor[1] = RDCCLAMP(Marker.color[1], 0.0f, 1.0f); + draw.markerColor[2] = RDCCLAMP(Marker.color[2], 0.0f, 1.0f); + draw.markerColor[3] = RDCCLAMP(Marker.color[3], 0.0f, 1.0f); + + AddDrawcall(draw, false); } - - DrawcallDescription draw; - draw.name = name; - draw.flags |= DrawFlags::SetMarker; - - draw.markerColor[0] = RDCCLAMP(color[0], 0.0f, 1.0f); - draw.markerColor[1] = RDCCLAMP(color[1], 0.0f, 1.0f); - draw.markerColor[2] = RDCCLAMP(color[2], 0.0f, 1.0f); - draw.markerColor[3] = RDCCLAMP(color[3], 0.0f, 1.0f); - - AddDrawcall(draw, false); } return true; @@ -2869,15 +2710,99 @@ void WrappedVulkan::vkCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), pMarker); - if(m_State >= WRITING) + if(IsCaptureMode(m_State)) { VkResourceRecord *record = GetRecord(commandBuffer); CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_vkCmdDebugMarkerInsertEXT(localSerialiser, commandBuffer, pMarker); + ser.SetDrawChunk(); + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdDebugMarkerInsertEXT); + Serialise_vkCmdDebugMarkerInsertEXT(ser, commandBuffer, pMarker); record->AddChunk(scope.Get()); } } + +INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); + +INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkBeginCommandBuffer, VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo); + +INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkEndCommandBuffer, VkCommandBuffer commandBuffer); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginRenderPass, VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + VkSubpassContents contents); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdNextSubpass, VkCommandBuffer commandBuffer, + VkSubpassContents contents); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndRenderPass, VkCommandBuffer commandBuffer); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindPipeline, VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindDescriptorSets, VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, + uint32_t firstSet, uint32_t setCount, + const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, + const uint32_t *pDynamicOffsets); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindIndexBuffer, VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBindVertexBuffers, VkCommandBuffer commandBuffer, + uint32_t firstBinding, uint32_t bindingCount, + const VkBuffer *pBuffers, const VkDeviceSize *pOffsets); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdUpdateBuffer, VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, + const uint32_t *pData); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdFillBuffer, VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize fillSize, + uint32_t data); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdPushConstants, VkCommandBuffer commandBuffer, + VkPipelineLayout layout, VkShaderStageFlags stageFlags, + uint32_t offset, uint32_t size, const void *pValues); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdPipelineBarrier, VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, + const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdWriteTimestamp, VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, + uint32_t query); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdCopyQueryPoolResults, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, + VkQueryResultFlags flags); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginQuery, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndQuery, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdResetQueryPool, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdExecuteCommands, VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdDebugMarkerBeginEXT, VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT *pMarker); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdDebugMarkerEndEXT, VkCommandBuffer commandBuffer); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdDebugMarkerInsertEXT, VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT *pMarker);