1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[dxvk] Rework queue family selection

This allows us to support multiple queues more easily.
This commit is contained in:
Philip Rebohle 2019-06-28 00:17:56 +02:00
parent 110fc8f833
commit 1c39765b86
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 92 additions and 59 deletions

View File

@ -1,4 +1,5 @@
#include <cstring> #include <cstring>
#include <unordered_set>
#include "dxvk_adapter.h" #include "dxvk_adapter.h"
#include "dxvk_device.h" #include "dxvk_device.h"
@ -88,22 +89,25 @@ namespace dxvk {
} }
uint32_t DxvkAdapter::graphicsQueueFamily() const { DxvkAdapterQueueIndices DxvkAdapter::findQueueFamilies() const {
for (uint32_t i = 0; i < m_queueFamilies.size(); i++) { uint32_t graphicsQueue = findQueueFamily(
if (m_queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT,
return i; VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT);
}
throw DxvkError("DxvkAdapter: No graphics queue found"); uint32_t transferQueue = findQueueFamily(
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT,
VK_QUEUE_TRANSFER_BIT);
if (transferQueue == VK_QUEUE_FAMILY_IGNORED)
transferQueue = graphicsQueue;
DxvkAdapterQueueIndices queues;
queues.graphics = graphicsQueue;
queues.transfer = transferQueue;
return queues;
} }
uint32_t DxvkAdapter::presentQueueFamily() const {
// TODO Implement properly
return this->graphicsQueueFamily();
}
bool DxvkAdapter::checkFeatureSupport(const DxvkDeviceFeatures& required) const { bool DxvkAdapter::checkFeatureSupport(const DxvkDeviceFeatures& required) const {
return (m_deviceFeatures.core.features.robustBufferAccess return (m_deviceFeatures.core.features.robustBufferAccess
|| !required.core.features.robustBufferAccess) || !required.core.features.robustBufferAccess)
@ -324,26 +328,25 @@ namespace dxvk {
overallocInfo.pNext = nullptr; overallocInfo.pNext = nullptr;
overallocInfo.overallocationBehavior = VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD; overallocInfo.overallocationBehavior = VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD;
// Create one single queue for graphics and present // Create the requested queues
float queuePriority = 1.0f; float queuePriority = 1.0f;
std::vector<VkDeviceQueueCreateInfo> queueInfos; std::vector<VkDeviceQueueCreateInfo> queueInfos;
std::unordered_set<uint32_t> queueFamiliySet;
DxvkAdapterQueueIndices queueFamilies = findQueueFamilies();
queueFamiliySet.insert(queueFamilies.graphics);
queueFamiliySet.insert(queueFamilies.transfer);
uint32_t gIndex = this->graphicsQueueFamily(); for (uint32_t family : queueFamiliySet) {
uint32_t pIndex = this->presentQueueFamily(); VkDeviceQueueCreateInfo graphicsQueue;
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
VkDeviceQueueCreateInfo graphicsQueue; graphicsQueue.pNext = nullptr;
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; graphicsQueue.flags = 0;
graphicsQueue.pNext = nullptr; graphicsQueue.queueFamilyIndex = family;
graphicsQueue.flags = 0; graphicsQueue.queueCount = 1;
graphicsQueue.queueFamilyIndex = gIndex; graphicsQueue.pQueuePriorities = &queuePriority;
graphicsQueue.queueCount = 1; queueInfos.push_back(graphicsQueue);
graphicsQueue.pQueuePriorities = &queuePriority;
queueInfos.push_back(graphicsQueue);
if (pIndex != gIndex) {
VkDeviceQueueCreateInfo presentQueue = graphicsQueue;
presentQueue.queueFamilyIndex = pIndex;
queueInfos.push_back(presentQueue);
} }
VkDeviceCreateInfo info; VkDeviceCreateInfo info;
@ -541,6 +544,18 @@ namespace dxvk {
m_vki->vkGetPhysicalDeviceQueueFamilyProperties( m_vki->vkGetPhysicalDeviceQueueFamilyProperties(
m_handle, &numQueueFamilies, m_queueFamilies.data()); m_handle, &numQueueFamilies, m_queueFamilies.data());
} }
uint32_t DxvkAdapter::findQueueFamily(
VkQueueFlags mask,
VkQueueFlags flags) const {
for (uint32_t i = 0; i < m_queueFamilies.size(); i++) {
if ((m_queueFamilies[i].queueFlags & mask) == flags)
return i;
}
return VK_QUEUE_FAMILY_IGNORED;
}
void DxvkAdapter::logNameList(const DxvkNameList& names) { void DxvkAdapter::logNameList(const DxvkNameList& names) {

View File

@ -41,6 +41,14 @@ namespace dxvk {
uint32_t heapCount; uint32_t heapCount;
DxvkAdapterMemoryHeapInfo heaps[VK_MAX_MEMORY_HEAPS]; DxvkAdapterMemoryHeapInfo heaps[VK_MAX_MEMORY_HEAPS];
}; };
/**
* \brief Retrieves queue indices
*/
struct DxvkAdapterQueueIndices {
uint32_t graphics;
uint32_t transfer;
};
/** /**
* \brief DXVK adapter * \brief DXVK adapter
@ -162,16 +170,10 @@ namespace dxvk {
VkImageFormatProperties& properties) const; VkImageFormatProperties& properties) const;
/** /**
* \brief Graphics queue family index * \brief Retrieves queue family indices
* \returns Graphics queue family index * \returns Indices for all queue families
*/ */
uint32_t graphicsQueueFamily() const; DxvkAdapterQueueIndices findQueueFamilies() const;
/**
* \brief Presentation queue family index
* \returns Presentation queue family index
*/
uint32_t presentQueueFamily() const;
/** /**
* \brief Tests whether all required features are supported * \brief Tests whether all required features are supported
@ -273,6 +275,10 @@ namespace dxvk {
void queryDeviceInfo(); void queryDeviceInfo();
void queryDeviceFeatures(); void queryDeviceFeatures();
void queryDeviceQueues(); void queryDeviceQueues();
uint32_t findQueueFamily(
VkQueueFlags mask,
VkQueueFlags flags) const;
static void logNameList(const DxvkNameList& names); static void logNameList(const DxvkNameList& names);

View File

@ -28,16 +28,9 @@ namespace dxvk {
m_metaPackObjects (new DxvkMetaPackObjects (vkd)), m_metaPackObjects (new DxvkMetaPackObjects (vkd)),
m_unboundResources (this), m_unboundResources (this),
m_submissionQueue (this) { m_submissionQueue (this) {
m_graphicsQueue.queueFamily = m_adapter->graphicsQueueFamily(); auto queueFamilies = m_adapter->findQueueFamilies();
m_presentQueue.queueFamily = m_adapter->presentQueueFamily(); m_queues.graphics = getQueue(queueFamilies.graphics, 0);
m_queues.transfer = getQueue(queueFamilies.transfer, 0);
m_vkd->vkGetDeviceQueue(m_vkd->device(),
m_graphicsQueue.queueFamily, 0,
&m_graphicsQueue.queueHandle);
m_vkd->vkGetDeviceQueue(m_vkd->device(),
m_presentQueue.queueFamily, 0,
&m_presentQueue.queueHandle);
} }
@ -76,10 +69,8 @@ namespace dxvk {
Rc<DxvkCommandList> DxvkDevice::createCommandList() { Rc<DxvkCommandList> DxvkDevice::createCommandList() {
Rc<DxvkCommandList> cmdList = m_recycledCommandLists.retrieveObject(); Rc<DxvkCommandList> cmdList = m_recycledCommandLists.retrieveObject();
if (cmdList == nullptr) { if (cmdList == nullptr)
cmdList = new DxvkCommandList(this, cmdList = new DxvkCommandList(this, m_queues.graphics.queueFamily);
m_adapter->graphicsQueueFamily());
}
return cmdList; return cmdList;
} }
@ -238,7 +229,7 @@ namespace dxvk {
VkSemaphore wakeSync) { VkSemaphore wakeSync) {
DxvkSubmitInfo submitInfo; DxvkSubmitInfo submitInfo;
submitInfo.cmdList = commandList; submitInfo.cmdList = commandList;
submitInfo.queue = m_graphicsQueue.queueHandle; submitInfo.queue = m_queues.graphics.queueHandle;
submitInfo.waitSync = waitSync; submitInfo.waitSync = waitSync;
submitInfo.wakeSync = wakeSync; submitInfo.wakeSync = wakeSync;
m_submissionQueue.submit(submitInfo); m_submissionQueue.submit(submitInfo);
@ -265,5 +256,14 @@ namespace dxvk {
void DxvkDevice::recycleDescriptorPool(const Rc<DxvkDescriptorPool>& pool) { void DxvkDevice::recycleDescriptorPool(const Rc<DxvkDescriptorPool>& pool) {
m_recycledDescriptorPools.returnObject(pool); m_recycledDescriptorPools.returnObject(pool);
} }
DxvkDeviceQueue DxvkDevice::getQueue(
uint32_t family,
uint32_t index) const {
VkQueue queue = VK_NULL_HANDLE;
m_vkd->vkGetDeviceQueue(m_vkd->device(), family, index, &queue);
return DxvkDeviceQueue { queue, family, index };
}
} }

View File

@ -42,8 +42,17 @@ namespace dxvk {
* queue family that it belongs to. * queue family that it belongs to.
*/ */
struct DxvkDeviceQueue { struct DxvkDeviceQueue {
uint32_t queueFamily = 0;
VkQueue queueHandle = VK_NULL_HANDLE; VkQueue queueHandle = VK_NULL_HANDLE;
uint32_t queueFamily = 0;
uint32_t queueIndex = 0;
};
/**
* \brief Device queue infos
*/
struct DxvkDeviceQueueSet {
DxvkDeviceQueue graphics;
DxvkDeviceQueue transfer;
}; };
/** /**
@ -109,7 +118,7 @@ namespace dxvk {
* \returns Graphics queue info * \returns Graphics queue info
*/ */
DxvkDeviceQueue graphicsQueue() const { DxvkDeviceQueue graphicsQueue() const {
return m_graphicsQueue; return m_queues.graphics;
} }
/** /**
@ -407,8 +416,7 @@ namespace dxvk {
sync::Spinlock m_statLock; sync::Spinlock m_statLock;
DxvkStatCounters m_statCounters; DxvkStatCounters m_statCounters;
DxvkDeviceQueue m_graphicsQueue; DxvkDeviceQueueSet m_queues;
DxvkDeviceQueue m_presentQueue;
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists; DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
DxvkRecycler<DxvkDescriptorPool, 16> m_recycledDescriptorPools; DxvkRecycler<DxvkDescriptorPool, 16> m_recycledDescriptorPools;
@ -421,6 +429,10 @@ namespace dxvk {
void recycleDescriptorPool( void recycleDescriptorPool(
const Rc<DxvkDescriptorPool>& pool); const Rc<DxvkDescriptorPool>& pool);
DxvkDeviceQueue getQueue(
uint32_t family,
uint32_t index) const;
/** /**
* \brief Dummy buffer handle * \brief Dummy buffer handle
* \returns Use for unbound vertex buffers. * \returns Use for unbound vertex buffers.