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 <unordered_set>
#include "dxvk_adapter.h"
#include "dxvk_device.h"
@ -88,19 +89,22 @@ namespace dxvk {
}
uint32_t DxvkAdapter::graphicsQueueFamily() const {
for (uint32_t i = 0; i < m_queueFamilies.size(); i++) {
if (m_queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
return i;
}
DxvkAdapterQueueIndices DxvkAdapter::findQueueFamilies() const {
uint32_t graphicsQueue = findQueueFamily(
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT,
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;
uint32_t DxvkAdapter::presentQueueFamily() const {
// TODO Implement properly
return this->graphicsQueueFamily();
DxvkAdapterQueueIndices queues;
queues.graphics = graphicsQueue;
queues.transfer = transferQueue;
return queues;
}
@ -324,26 +328,25 @@ namespace dxvk {
overallocInfo.pNext = nullptr;
overallocInfo.overallocationBehavior = VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD;
// Create one single queue for graphics and present
// Create the requested queues
float queuePriority = 1.0f;
std::vector<VkDeviceQueueCreateInfo> queueInfos;
uint32_t gIndex = this->graphicsQueueFamily();
uint32_t pIndex = this->presentQueueFamily();
std::unordered_set<uint32_t> queueFamiliySet;
DxvkAdapterQueueIndices queueFamilies = findQueueFamilies();
queueFamiliySet.insert(queueFamilies.graphics);
queueFamiliySet.insert(queueFamilies.transfer);
for (uint32_t family : queueFamiliySet) {
VkDeviceQueueCreateInfo graphicsQueue;
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
graphicsQueue.pNext = nullptr;
graphicsQueue.flags = 0;
graphicsQueue.queueFamilyIndex = gIndex;
graphicsQueue.queueFamilyIndex = family;
graphicsQueue.queueCount = 1;
graphicsQueue.pQueuePriorities = &queuePriority;
queueInfos.push_back(graphicsQueue);
if (pIndex != gIndex) {
VkDeviceQueueCreateInfo presentQueue = graphicsQueue;
presentQueue.queueFamilyIndex = pIndex;
queueInfos.push_back(presentQueue);
}
VkDeviceCreateInfo info;
@ -543,6 +546,18 @@ namespace dxvk {
}
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) {
for (uint32_t i = 0; i < names.count(); i++)
Logger::info(str::format(" ", names.name(i)));

View File

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

View File

@ -28,16 +28,9 @@ namespace dxvk {
m_metaPackObjects (new DxvkMetaPackObjects (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_graphicsQueue.queueFamily, 0,
&m_graphicsQueue.queueHandle);
m_vkd->vkGetDeviceQueue(m_vkd->device(),
m_presentQueue.queueFamily, 0,
&m_presentQueue.queueHandle);
auto queueFamilies = m_adapter->findQueueFamilies();
m_queues.graphics = getQueue(queueFamilies.graphics, 0);
m_queues.transfer = getQueue(queueFamilies.transfer, 0);
}
@ -76,10 +69,8 @@ namespace dxvk {
Rc<DxvkCommandList> DxvkDevice::createCommandList() {
Rc<DxvkCommandList> cmdList = m_recycledCommandLists.retrieveObject();
if (cmdList == nullptr) {
cmdList = new DxvkCommandList(this,
m_adapter->graphicsQueueFamily());
}
if (cmdList == nullptr)
cmdList = new DxvkCommandList(this, m_queues.graphics.queueFamily);
return cmdList;
}
@ -238,7 +229,7 @@ namespace dxvk {
VkSemaphore wakeSync) {
DxvkSubmitInfo submitInfo;
submitInfo.cmdList = commandList;
submitInfo.queue = m_graphicsQueue.queueHandle;
submitInfo.queue = m_queues.graphics.queueHandle;
submitInfo.waitSync = waitSync;
submitInfo.wakeSync = wakeSync;
m_submissionQueue.submit(submitInfo);
@ -266,4 +257,13 @@ namespace dxvk {
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.
*/
struct DxvkDeviceQueue {
uint32_t queueFamily = 0;
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
*/
DxvkDeviceQueue graphicsQueue() const {
return m_graphicsQueue;
return m_queues.graphics;
}
/**
@ -407,8 +416,7 @@ namespace dxvk {
sync::Spinlock m_statLock;
DxvkStatCounters m_statCounters;
DxvkDeviceQueue m_graphicsQueue;
DxvkDeviceQueue m_presentQueue;
DxvkDeviceQueueSet m_queues;
DxvkRecycler<DxvkCommandList, 16> m_recycledCommandLists;
DxvkRecycler<DxvkDescriptorPool, 16> m_recycledDescriptorPools;
@ -421,6 +429,10 @@ namespace dxvk {
void recycleDescriptorPool(
const Rc<DxvkDescriptorPool>& pool);
DxvkDeviceQueue getQueue(
uint32_t family,
uint32_t index) const;
/**
* \brief Dummy buffer handle
* \returns Use for unbound vertex buffers.