diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index d6fb1d433..47ccce24b 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -18,12 +18,16 @@ namespace dxvk { m_metaClearObjects(new DxvkMetaClearObjects (vkd)), m_unboundResources(this), m_submissionQueue (this) { + m_graphicsQueue.queueFamily = m_adapter->graphicsQueueFamily(); + m_presentQueue.queueFamily = m_adapter->presentQueueFamily(); + m_vkd->vkGetDeviceQueue(m_vkd->device(), - m_adapter->graphicsQueueFamily(), 0, - &m_graphicsQueue); + m_graphicsQueue.queueFamily, 0, + &m_graphicsQueue.queueHandle); + m_vkd->vkGetDeviceQueue(m_vkd->device(), - m_adapter->presentQueueFamily(), 0, - &m_presentQueue); + m_presentQueue.queueFamily, 0, + &m_presentQueue.queueHandle); } @@ -202,7 +206,7 @@ namespace dxvk { std::lock_guard statLock(m_statLock); m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1); - return m_vkd->vkQueuePresentKHR(m_presentQueue, &presentInfo); + return m_vkd->vkQueuePresentKHR(m_presentQueue.queueHandle, &presentInfo); } } @@ -234,7 +238,8 @@ namespace dxvk { m_statCounters.addCtr(DxvkStatCounter::QueueSubmitCount, 1); status = commandList->submit( - m_graphicsQueue, waitSemaphore, wakeSemaphore); + m_graphicsQueue.queueHandle, + waitSemaphore, wakeSemaphore); } if (status == VK_SUCCESS) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index c7f44a46f..d40755746 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -27,6 +27,17 @@ namespace dxvk { class DxvkInstance; + /** + * \brief Device queue + * + * Stores a Vulkan queue and the + * queue family that it belongs to. + */ + struct DxvkDeviceQueue { + uint32_t queueFamily = 0; + VkQueue queueHandle = VK_NULL_HANDLE; + }; + /** * \brief DXVK device * @@ -66,6 +77,17 @@ namespace dxvk { return m_vkd->device(); } + /** + * \brief Graphics queue properties + * + * Handle and queue family index of + * the queue used for rendering. + * \returns Graphics queue info + */ + DxvkDeviceQueue graphicsQueue() const { + return m_graphicsQueue; + } + /** * \brief The adapter * @@ -291,6 +313,27 @@ namespace dxvk { const Rc& waitSync, const Rc& wakeSync); + /** + * \brief Locks submission queue + * + * Since Vulkan queues are only meant to be accessed + * from one thread at a time, external libraries need + * to lock the queue before submitting command buffers. + */ + void lockSubmission() { + m_submissionLock.lock(); + } + + /** + * \brief Unlocks submission queue + * + * Releases the Vulkan queues again so that DXVK + * itself can use them for submissions again. + */ + void unlockSubmission() { + m_submissionLock.unlock(); + } + /** * \brief Waits until the device becomes idle * @@ -318,9 +361,9 @@ namespace dxvk { sync::Spinlock m_statLock; DxvkStatCounters m_statCounters; - std::mutex m_submissionLock; - VkQueue m_graphicsQueue = VK_NULL_HANDLE; - VkQueue m_presentQueue = VK_NULL_HANDLE; + std::mutex m_submissionLock; + DxvkDeviceQueue m_graphicsQueue; + DxvkDeviceQueue m_presentQueue; DxvkRecycler m_recycledCommandLists; DxvkRecycler m_recycledStagingBuffers;