From 05a827703bffb87737a22604a2932030f4505da7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 16:49:22 +0200 Subject: [PATCH] [dxvk] Add fence support to command list Co-authored-by: Derek Lesho --- src/dxvk/dxvk_cmdlist.cpp | 23 +++++++++++++++++++++-- src/dxvk/dxvk_cmdlist.h | 26 +++++++++++++++++++++++++- src/dxvk/dxvk_context.cpp | 10 ++++++++++ src/dxvk/dxvk_context.h | 22 +++++++++++++++++++++- src/dxvk/dxvk_fence.h | 17 +++++++++++++++++ 5 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 255725b32..107850753 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -106,7 +106,7 @@ namespace dxvk { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = m_sdmaSemaphore; - waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitSync.push_back(waitInfo); } } @@ -126,7 +126,7 @@ namespace dxvk { if (waitSemaphore) { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = waitSemaphore; - waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitSync.push_back(waitInfo); } @@ -137,6 +137,22 @@ namespace dxvk { m_submission.wakeSync.push_back(signalInfo); } + for (const auto& entry : m_waitSemaphores) { + VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + waitInfo.semaphore = entry.fence->handle(); + waitInfo.value = entry.value; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; + m_submission.waitSync.push_back(waitInfo); + } + + for (const auto& entry : m_signalSemaphores) { + VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + signalInfo.semaphore = entry.fence->handle(); + signalInfo.value = entry.value; + signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + m_submission.wakeSync.push_back(signalInfo); + } + return submitToQueue(graphics.queueHandle, m_fence, m_submission); } @@ -207,6 +223,9 @@ namespace dxvk { descriptorPools.second->recycleDescriptorPool(descriptorPools.first); m_descriptorPools.clear(); + + m_waitSemaphores.clear(); + m_signalSemaphores.clear(); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 4139f020d..f58f725d2 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -5,6 +5,7 @@ #include "dxvk_bind_mask.h" #include "dxvk_buffer.h" #include "dxvk_descriptor.h" +#include "dxvk_fence.h" #include "dxvk_gpu_event.h" #include "dxvk_gpu_query.h" #include "dxvk_lifetime.h" @@ -195,6 +196,26 @@ namespace dxvk { m_signalTracker.notify(); } + /** + * \brief Waits for fence + * + * \param [in] fence Fence to wait on + * \param [in] value Value to wait for + */ + void waitFence(Rc fence, uint64_t value) { + m_waitSemaphores.emplace_back(std::move(fence), value); + } + + /** + * \brief Signals fence + * + * \param [in] fence Fence to signal + * \param [in] value Value to signal to + */ + void signalFence(Rc fence, uint64_t value) { + m_signalSemaphores.emplace_back(std::move(fence), value); + } + /** * \brief Resets the command list * @@ -784,7 +805,7 @@ namespace dxvk { VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE; VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; - + DxvkCmdBufferFlags m_cmdBuffersUsed; DxvkLifetimeTracker m_resources; DxvkSignalTracker m_signalTracker; @@ -794,6 +815,9 @@ namespace dxvk { DxvkStatCounters m_statCounters; DxvkQueueSubmission m_submission; + std::vector m_waitSemaphores; + std::vector m_signalSemaphores; + std::vector, Rc>> m_descriptorPools; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9064a98ae..b1716c326 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2646,6 +2646,16 @@ namespace dxvk { } + void DxvkContext::waitFence(const Rc& fence, uint64_t value) { + m_cmd->waitFence(fence, value); + } + + + void DxvkContext::signalFence(const Rc& fence, uint64_t value) { + m_cmd->signalFence(fence, value); + } + + void DxvkContext::beginDebugLabel(VkDebugUtilsLabelEXT *label) { if (!m_device->instance()->extensions().extDebugUtils) return; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 1f1c1fd54..3e9eff4e3 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1088,7 +1088,27 @@ namespace dxvk { void signal( const Rc& signal, uint64_t value); - + + /** + * \brief Waits for fence + * + * Stalls current command list execution until + * the fence reaches the given value or higher. + * \param [in] fence Fence to wait on + * \param [in] value Value to wait on + */ + void waitFence(const Rc& fence, uint64_t value); + + /** + * \brief Signals fence + * + * Signals fence to the given value once the current + * command list execution completes on the GPU. + * \param [in] fence Fence to signal + * \param [in] value Value to signal + */ + void signalFence(const Rc& fence, uint64_t value); + /** * \brief Begins a debug label region * \param [in] label The debug label diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index a533d22ba..c9fc243b1 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include "dxvk_resource.h" @@ -10,6 +12,7 @@ namespace dxvk { class DxvkDevice; + class DxvkFence; using DxvkFenceEvent = std::function; @@ -20,6 +23,20 @@ namespace dxvk { uint64_t initialValue; }; + /** + * \brief Fence-value pair + */ + struct DxvkFenceValuePair { + DxvkFenceValuePair() { } + DxvkFenceValuePair(Rc&& fence_, uint64_t value_) + : fence(std::move(fence_)), value(value_) { } + DxvkFenceValuePair(const Rc& fence_, uint64_t value_) + : fence(fence_), value(value_) { } + + Rc fence; + uint64_t value; + }; + /** * \brief Fence *