diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 9e8464fa..49eaccf2 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -7,9 +7,10 @@ namespace dxvk { const Rc& vkd, DxvkDevice* device, uint32_t queueFamily) - : m_vkd (vkd), - m_descAlloc (vkd), - m_stagingAlloc(device) { + : m_vkd (vkd), + m_cmdBuffersUsed(0), + m_descAlloc (vkd), + m_stagingAlloc (device) { VkFenceCreateInfo fenceInfo; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.pNext = nullptr; @@ -52,8 +53,13 @@ namespace dxvk { VkQueue queue, VkSemaphore waitSemaphore, VkSemaphore wakeSemaphore) { - std::array cmdBuffers - = {{ m_initBuffer, m_execBuffer }}; + std::array cmdBuffers; + uint32_t cmdBufferCount = 0; + + if (m_cmdBuffersUsed.test(DxvkCmdBufferFlag::InitBuffer)) + cmdBuffers[cmdBufferCount++] = m_initBuffer; + if (m_cmdBuffersUsed.test(DxvkCmdBufferFlag::ExecBuffer)) + cmdBuffers[cmdBufferCount++] = m_execBuffer; const VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; @@ -64,7 +70,7 @@ namespace dxvk { info.waitSemaphoreCount = waitSemaphore == VK_NULL_HANDLE ? 0 : 1; info.pWaitSemaphores = &waitSemaphore; info.pWaitDstStageMask = &waitStageMask; - info.commandBufferCount = cmdBuffers.size(); + info.commandBufferCount = cmdBufferCount; info.pCommandBuffers = cmdBuffers.data(); info.signalSemaphoreCount = wakeSemaphore == VK_NULL_HANDLE ? 0 : 1; info.pSignalSemaphores = &wakeSemaphore; @@ -102,6 +108,10 @@ namespace dxvk { if (m_vkd->vkResetFences(m_vkd->device(), 1, &m_fence) != VK_SUCCESS) Logger::err("DxvkCommandList: Failed to reset fence"); + + // Unconditionally mark the exec buffer as used. There + // is virtually no use case where this isn't correct. + m_cmdBuffersUsed.set(DxvkCmdBufferFlag::ExecBuffer); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 1feb7706..756aa330 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -16,6 +16,19 @@ namespace dxvk { + /** + * \brief Command buffer flags + * + * A set of flags used to specify which of + * the command buffers need to be submitted. + */ + enum class DxvkCmdBufferFlag : uint32_t { + InitBuffer = 0, + ExecBuffer = 1, + }; + + using DxvkCmdBufferFlags = Flags; + /** * \brief DXVK command list * @@ -468,7 +481,9 @@ namespace dxvk { VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount) { - m_vkd->vkCmdResetQueryPool(m_execBuffer, + m_cmdBuffersUsed.set(DxvkCmdBufferFlag::InitBuffer); + + m_vkd->vkCmdResetQueryPool(m_initBuffer, queryPool, firstQuery, queryCount); } @@ -564,6 +579,7 @@ namespace dxvk { VkCommandBuffer m_execBuffer; VkCommandBuffer m_initBuffer; + DxvkCmdBufferFlags m_cmdBuffersUsed; DxvkLifetimeTracker m_resources; DxvkDescriptorAlloc m_descAlloc; DxvkStagingAlloc m_stagingAlloc;