diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index bf979715d..2026a9162 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -194,6 +194,7 @@ namespace dxvk { const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; + const auto& sparse = m_device->queues().sparse; m_commandSubmission.reset(); @@ -203,15 +204,41 @@ namespace dxvk { const auto& cmd = m_cmdSubmissions[i]; + auto sparseBind = cmd.sparseBind + ? &m_cmdSparseBinds[cmd.sparseCmd] + : nullptr; + + if (sparseBind) { + // Sparse bindig needs to serialize command execution, so wait + // for any prior submissions, then block any subsequent ones + sparseBind->waitSemaphore(semaphore, semaphoreValue); + sparseBind->signalSemaphore(semaphore, ++semaphoreValue); + + m_commandSubmission.waitSemaphore(semaphore, semaphoreValue, + VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } + if (isFirst) { // Wait for per-command list semaphores on first submission for (const auto& entry : m_waitSemaphores) { - m_commandSubmission.waitSemaphore( - entry.fence->handle(), - entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + if (sparseBind) { + sparseBind->waitSemaphore( + entry.fence->handle(), + entry.value); + } else { + m_commandSubmission.waitSemaphore( + entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } } } + // Execute sparse bind + if (sparseBind) { + if ((status = sparseBind->submit(m_device, sparse.queueHandle))) + return status; + } + // Submit transfer commands as necessary if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) m_commandSubmission.executeCommandBuffer(cmd.sdmaBuffer); @@ -353,7 +380,9 @@ namespace dxvk { m_waitSemaphores.clear(); m_signalSemaphores.clear(); + m_cmdSubmissions.clear(); + m_cmdSparseBinds.clear(); m_wsiSemaphores = vk::PresenterSync(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 7d41777f2..6188b5c48 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -15,6 +15,7 @@ #include "dxvk_limits.h" #include "dxvk_pipelayout.h" #include "dxvk_signal.h" +#include "dxvk_sparse.h" #include "dxvk_staging.h" #include "dxvk_stats.h" @@ -122,6 +123,8 @@ namespace dxvk { VkCommandBuffer execBuffer = VK_NULL_HANDLE; VkCommandBuffer initBuffer = VK_NULL_HANDLE; VkCommandBuffer sdmaBuffer = VK_NULL_HANDLE; + VkBool32 sparseBind = VK_FALSE; + uint32_t sparseCmd = 0; }; @@ -990,6 +993,7 @@ namespace dxvk { std::vector m_signalSemaphores; std::vector m_cmdSubmissions; + std::vector m_cmdSparseBinds; std::vector,