From 0a3ac0dbd631f341c7f703d0ed0f435efe251bed Mon Sep 17 00:00:00 2001 From: Qining Lu Date: Wed, 3 May 2017 12:27:09 -0400 Subject: [PATCH] Vulkan MEC: Finish secondary command buffers prior to primary ones According to spec, when primary command buffers call vkCmdExecuteCommands, all the related secondary command buffers must be in pending/executable state, cannot be in recording state. --- gapii/cc/vulkan_mid_execution.cpp | 111 +++++++++++++++++++----------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/gapii/cc/vulkan_mid_execution.cpp b/gapii/cc/vulkan_mid_execution.cpp index 2113ad1bf1..f2769bc1c2 100644 --- a/gapii/cc/vulkan_mid_execution.cpp +++ b/gapii/cc/vulkan_mid_execution.cpp @@ -1647,53 +1647,86 @@ void VulkanSpy::EnumerateVulkanResources(CallObserver* observer) { &pool.mVulkanHandle); } - // Recreate and begin command buffers + // Helper function to recreate and begin a given command buffer object. + auto recreate_and_begin_cmd_buf = [this]( + CallObserver* observer, std::shared_ptr cmdBuff) { + VkCommandBufferAllocateInfo allocate_info{ + VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + nullptr, cmdBuff->mPool, cmdBuff->mLevel, 1}; + VkCommandBufferBeginInfo begin_info{ + VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, + 0, nullptr}; + VkCommandBufferInheritanceInfo inheritance_info{ + VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + nullptr, + 0, + 0, + 0, + 0, + 0, + 0}; + if (cmdBuff->mBeginInfo) { + begin_info.mflags = cmdBuff->mBeginInfo->mFlags; + if (cmdBuff->mBeginInfo->mInherited) { + inheritance_info.mrenderPass = + cmdBuff->mBeginInfo->mInheritedRenderPass; + inheritance_info.msubpass = cmdBuff->mBeginInfo->mInheritedSubpass; + inheritance_info.mframebuffer = + cmdBuff->mBeginInfo->mInheritedFramebuffer; + inheritance_info.mocclusionQueryEnable = + cmdBuff->mBeginInfo->mInheritedOcclusionQuery; + inheritance_info.mqueryFlags = + cmdBuff->mBeginInfo->mInheritedQueryFlags; + inheritance_info.mpipelineStatistics = + cmdBuff->mBeginInfo->mInheritedPipelineStatsFlags; + begin_info.mpInheritanceInfo = &inheritance_info; + } + } + RecreateAndBeginCommandBuffer(observer, cmdBuff->mDevice, &allocate_info, + cmdBuff->mBeginInfo ? &begin_info : nullptr, + &cmdBuff->mVulkanHandle); + }; + + // Helper function to fill and end a given command buffer object. + auto fill_and_end_cmd_buf = [this](CallObserver * observer, + std::shared_ptr cmdBuff) { + for (auto& recreate : cmdBuff->recreateCommands) { + recreate(observer); + } + if (cmdBuff->mRecording == RecordingState::COMPLETED) { + RecreateEndCommandBuffer(observer, cmdBuff->mVulkanHandle); + } + }; + + // Recreate and begin all the secondary command buffers for (auto& commandBuffer: CommandBuffers) { - auto& cmdBuff = *commandBuffer.second; - VkCommandBufferAllocateInfo allocate_info { - VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - nullptr, - cmdBuff.mPool, - cmdBuff.mLevel, - 1 - }; - VkCommandBufferBeginInfo begin_info { - VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - nullptr, - 0, - nullptr - }; - VkCommandBufferInheritanceInfo inheritance_info { - VkStructureType::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, - nullptr, - 0, 0, 0, 0, 0, 0 - }; - if (cmdBuff.mBeginInfo) { - begin_info.mflags = cmdBuff.mBeginInfo->mFlags; - if (cmdBuff.mBeginInfo->mInherited) { - inheritance_info.mrenderPass = cmdBuff.mBeginInfo->mInheritedRenderPass; - inheritance_info.msubpass = cmdBuff.mBeginInfo->mInheritedSubpass; - inheritance_info.mframebuffer = cmdBuff.mBeginInfo->mInheritedFramebuffer; - inheritance_info.mocclusionQueryEnable = cmdBuff.mBeginInfo->mInheritedOcclusionQuery; - inheritance_info.mqueryFlags = cmdBuff.mBeginInfo->mInheritedQueryFlags; - inheritance_info.mpipelineStatistics = cmdBuff.mBeginInfo->mInheritedPipelineStatsFlags; - begin_info.mpInheritanceInfo = &inheritance_info; - } + auto cmdBuff = commandBuffer.second; + if (cmdBuff->mLevel == VkCommandBufferLevel::VK_COMMAND_BUFFER_LEVEL_SECONDARY) { + recreate_and_begin_cmd_buf(observer, cmdBuff); } - RecreateAndBeginCommandBuffer(observer, cmdBuff.mDevice, - &allocate_info, cmdBuff.mBeginInfo? &begin_info: nullptr, &cmdBuff.mVulkanHandle); } - // Re-record commands and end for the command buffers + // Re-record commands and end for all the secondary command buffers for (auto& commandBuffer: CommandBuffers) { - auto& cmdBuff = *commandBuffer.second; + auto cmdBuff = commandBuffer.second; + if (cmdBuff->mLevel == VkCommandBufferLevel::VK_COMMAND_BUFFER_LEVEL_SECONDARY) { + fill_and_end_cmd_buf(observer, cmdBuff); + } + } - for (auto& recreate: cmdBuff.recreateCommands) { - recreate(observer); + // Recreate and begin primary command buffers + for (auto& commandBuffer: CommandBuffers) { + auto cmdBuff = commandBuffer.second; + if (cmdBuff->mLevel == VkCommandBufferLevel::VK_COMMAND_BUFFER_LEVEL_PRIMARY) { + recreate_and_begin_cmd_buf(observer, cmdBuff); } + } - if (cmdBuff.mRecording == RecordingState::COMPLETED) { - RecreateEndCommandBuffer(observer, cmdBuff.mVulkanHandle); + // Re-record commands and end for all the primary command buffers + for (auto& commandBuffer: CommandBuffers) { + auto cmdBuff = commandBuffer.second; + if (cmdBuff->mLevel == VkCommandBufferLevel::VK_COMMAND_BUFFER_LEVEL_PRIMARY) { + fill_and_end_cmd_buf(observer, cmdBuff); } } }