mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +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 <unordered_set>
|
||||
|
||||
#include "dxvk_adapter.h"
|
||||
#include "dxvk_device.h"
|
||||
@ -88,22 +89,25 @@ 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;
|
||||
|
||||
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 {
|
||||
return (m_deviceFeatures.core.features.robustBufferAccess
|
||||
|| !required.core.features.robustBufferAccess)
|
||||
@ -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;
|
||||
|
||||
std::unordered_set<uint32_t> queueFamiliySet;
|
||||
|
||||
DxvkAdapterQueueIndices queueFamilies = findQueueFamilies();
|
||||
queueFamiliySet.insert(queueFamilies.graphics);
|
||||
queueFamiliySet.insert(queueFamilies.transfer);
|
||||
|
||||
uint32_t gIndex = this->graphicsQueueFamily();
|
||||
uint32_t pIndex = this->presentQueueFamily();
|
||||
|
||||
VkDeviceQueueCreateInfo graphicsQueue;
|
||||
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
graphicsQueue.pNext = nullptr;
|
||||
graphicsQueue.flags = 0;
|
||||
graphicsQueue.queueFamilyIndex = gIndex;
|
||||
graphicsQueue.queueCount = 1;
|
||||
graphicsQueue.pQueuePriorities = &queuePriority;
|
||||
queueInfos.push_back(graphicsQueue);
|
||||
|
||||
if (pIndex != gIndex) {
|
||||
VkDeviceQueueCreateInfo presentQueue = graphicsQueue;
|
||||
presentQueue.queueFamilyIndex = pIndex;
|
||||
queueInfos.push_back(presentQueue);
|
||||
for (uint32_t family : queueFamiliySet) {
|
||||
VkDeviceQueueCreateInfo graphicsQueue;
|
||||
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
graphicsQueue.pNext = nullptr;
|
||||
graphicsQueue.flags = 0;
|
||||
graphicsQueue.queueFamilyIndex = family;
|
||||
graphicsQueue.queueCount = 1;
|
||||
graphicsQueue.pQueuePriorities = &queuePriority;
|
||||
queueInfos.push_back(graphicsQueue);
|
||||
}
|
||||
|
||||
VkDeviceCreateInfo info;
|
||||
@ -541,6 +544,18 @@ namespace dxvk {
|
||||
m_vki->vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
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) {
|
||||
|
@ -41,6 +41,14 @@ namespace dxvk {
|
||||
uint32_t heapCount;
|
||||
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
|
||||
@ -273,6 +275,10 @@ namespace dxvk {
|
||||
void queryDeviceInfo();
|
||||
void queryDeviceFeatures();
|
||||
void queryDeviceQueues();
|
||||
|
||||
uint32_t findQueueFamily(
|
||||
VkQueueFlags mask,
|
||||
VkQueueFlags flags) const;
|
||||
|
||||
static void logNameList(const DxvkNameList& names);
|
||||
|
||||
|
@ -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);
|
||||
@ -265,5 +256,14 @@ namespace dxvk {
|
||||
void DxvkDevice::recycleDescriptorPool(const Rc<DxvkDescriptorPool>& 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.
|
||||
*/
|
||||
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user