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:
parent
110fc8f833
commit
1c39765b86
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user