diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index 16064bdc02..5f9f833c40 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -53,6 +53,8 @@ namespace vsg AllocationCallbacks* getAllocationCallbacks() { return _allocator.get(); } const AllocationCallbacks* getAllocationCallbacks() const { return _allocator.get(); } + const Queues& getQueues() const { return _queues; } + ref_ptr getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex = 0); const Extensions* getExtensions() const { return _extensions.get(); } @@ -83,7 +85,7 @@ namespace vsg ref_ptr _allocator; ref_ptr _extensions; - std::list> _queues; + Queues _queues; }; VSG_type_name(vsg::Device); diff --git a/include/vsg/vk/Queue.h b/include/vsg/vk/Queue.h index 1012a2a2d8..e4dbc167e7 100644 --- a/include/vsg/vk/Queue.h +++ b/include/vsg/vk/Queue.h @@ -30,6 +30,7 @@ namespace vsg operator VkQueue() const { return _vkQueue; } VkQueue vk() const { return _vkQueue; } + VkQueueFlags queueFlags() const { return _queueFlags; } uint32_t queueFamilyIndex() const { return _queueFamilyIndex; } uint32_t queueIndex() const { return _queueIndex; } @@ -42,7 +43,7 @@ namespace vsg VkResult waitIdle(); protected: - Queue(VkQueue queue, uint32_t queueFamilyIndex, uint32_t queueIndex); + Queue(VkQueue queue, VkQueueFlags queueFlags, uint32_t queueFamilyIndex, uint32_t queueIndex); virtual ~Queue(); Queue() = delete; @@ -53,10 +54,13 @@ namespace vsg friend class Device; VkQueue _vkQueue; + VkQueueFlags _queueFlags; uint32_t _queueFamilyIndex; uint32_t _queueIndex; std::mutex _mutex; }; VSG_type_name(vsg::Queue); + using Queues = std::vector>; + } // namespace vsg diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index dacc9396b1..3b33f85ff0 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -454,7 +454,29 @@ void Viewer::assignRecordAndSubmitTaskAndPresentation(CommandGraphs in_commandGr uint32_t numBuffers = 3; auto device = deviceQueueFamily.device; - uint32_t transferQueueFamily = device->getPhysicalDevice()->getQueueFamily(VK_QUEUE_TRANSFER_BIT); + + // get main queue used for RecordAndSubmitTask + ref_ptr mainQueue = device->getQueue(deviceQueueFamily.queueFamily); + + // get presentat queue if required/supported + ref_ptr presentQueue; + if (deviceQueueFamily.presentFamily >= 0) presentQueue = device->getQueue(deviceQueueFamily.presentFamily); + + // get an appropriate transfer queue + ref_ptr transferQueue = mainQueue; + + VkQueueFlags transferQueueFlags = VK_QUEUE_TRANSFER_BIT | VK_QUEUE_GRAPHICS_BIT; // use VK_QUEUE_GRAPHICS_BIT to ensure we can blit images + for (auto& queue : device->getQueues()) + { + if ((queue->queueFlags() & transferQueueFlags) == transferQueueFlags) + { + if (queue != mainQueue) + { + transferQueue = queue; + break; + } + } + } if (deviceQueueFamily.presentFamily >= 0) { @@ -474,11 +496,11 @@ void Viewer::assignRecordAndSubmitTaskAndPresentation(CommandGraphs in_commandGr recordAndSubmitTask->commandGraphs = commandGraphs; recordAndSubmitTask->signalSemaphores.emplace_back(renderFinishedSemaphore); recordAndSubmitTask->windows = windows; - recordAndSubmitTask->queue = device->getQueue(deviceQueueFamily.queueFamily); + recordAndSubmitTask->queue = mainQueue; recordAndSubmitTasks.emplace_back(recordAndSubmitTask); - recordAndSubmitTask->earlyTransferTask->transferQueue = device->getQueue(transferQueueFamily); - recordAndSubmitTask->lateTransferTask->transferQueue = device->getQueue(transferQueueFamily); + recordAndSubmitTask->earlyTransferTask->transferQueue = transferQueue; + recordAndSubmitTask->lateTransferTask->transferQueue = transferQueue; auto presentation = vsg::Presentation::create(); presentation->waitSemaphores.emplace_back(renderFinishedSemaphore); @@ -492,11 +514,11 @@ void Viewer::assignRecordAndSubmitTaskAndPresentation(CommandGraphs in_commandGr // set up Submission with CommandBuffer and signals auto recordAndSubmitTask = vsg::RecordAndSubmitTask::create(device, numBuffers); recordAndSubmitTask->commandGraphs = commandGraphs; - recordAndSubmitTask->queue = device->getQueue(deviceQueueFamily.queueFamily); + recordAndSubmitTask->queue = mainQueue; recordAndSubmitTasks.emplace_back(recordAndSubmitTask); - recordAndSubmitTask->earlyTransferTask->transferQueue = device->getQueue(transferQueueFamily); - recordAndSubmitTask->lateTransferTask->transferQueue = device->getQueue(transferQueueFamily); + recordAndSubmitTask->earlyTransferTask->transferQueue = transferQueue; + recordAndSubmitTask->lateTransferTask->transferQueue = transferQueue; } } diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 42aef95699..34d7748a62 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -145,7 +145,18 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting VkQueue vk_queue; vkGetDeviceQueue(_device, queueInfo.queueFamilyIndex, queueIndex, &vk_queue); - ref_ptr queue(new Queue(vk_queue, queueInfo.queueFamilyIndex, queueIndex)); + VkQueueFlags queueFlags = 0; + + if (queueInfo.queueFamilyIndex < queueFamilyProperties.size()) + { + queueFlags = queueFamilyProperties[queueInfo.queueFamilyIndex].queueFlags; + } + else + { + warn("vsg::Device::Device(..) constructor unable to match queue family flags to PhysicalDevice queueFamilyProperties."); + } + + ref_ptr queue(new Queue(vk_queue, queueFlags, queueInfo.queueFamilyIndex, queueIndex)); _queues.emplace_back(queue); } } @@ -175,15 +186,11 @@ ref_ptr Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) if (queue->queueFamilyIndex() == queueFamilyIndex && queue->queueIndex() == queueIndex) return queue; } - debug("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failed back to next closest."); - for (auto& queue : _queues) { if (queue->queueFamilyIndex() == queueFamilyIndex) return queue; } - warn("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failed to find any suitable Queue."); - return {}; } diff --git a/src/vsg/vk/Queue.cpp b/src/vsg/vk/Queue.cpp index 5bf77d8022..d5a538c890 100644 --- a/src/vsg/vk/Queue.cpp +++ b/src/vsg/vk/Queue.cpp @@ -16,8 +16,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -Queue::Queue(VkQueue queue, uint32_t queueFamilyIndex, uint32_t queueIndex) : +Queue::Queue(VkQueue queue, VkQueueFlags queueFlags, uint32_t queueFamilyIndex, uint32_t queueIndex) : _vkQueue(queue), + _queueFlags(queueFlags), _queueFamilyIndex(queueFamilyIndex), _queueIndex(queueIndex) {