From 96561f3e4f8b9647d78d1abab208b2cfa2d720f5 Mon Sep 17 00:00:00 2001 From: Sebastian Gaida <gaida@ca-digit.com> Date: Tue, 18 May 2021 14:58:53 +0200 Subject: [PATCH] [#16] changed temp queueSetup Changed the temp queueSetup and moved the core functions into QueueManager --- config/Sources.cmake | 4 +- include/vkcv/Core.hpp | 6 +- include/vkcv/QueueManager.hpp | 36 +++++++ include/vkcv/Queues.hpp | 27 ----- src/vkcv/Core.cpp | 187 ++++++--------------------------- src/vkcv/QueueManager.cpp | 189 ++++++++++++++++++++++++++++++++++ src/vkcv/Queues.cpp | 71 ------------- 7 files changed, 260 insertions(+), 260 deletions(-) create mode 100644 include/vkcv/QueueManager.hpp delete mode 100644 include/vkcv/Queues.hpp create mode 100644 src/vkcv/QueueManager.cpp delete mode 100644 src/vkcv/Queues.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index dce76b39..b8c2dcbd 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -37,8 +37,8 @@ set(vkcv_sources ${vkcv_include}/vkcv/SyncResources.hpp ${vkcv_source}/vkcv/SyncResources.cpp - ${vkcv_include}/vkcv/Queues.hpp - ${vkcv_source}/vkcv/Queues.cpp + ${vkcv_include}/vkcv/QueueManager.hpp + ${vkcv_source}/vkcv/QueueManager.cpp ${vkcv_source}/vkcv/Surface.hpp ${vkcv_source}/vkcv/Surface.cpp diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index b7b553d7..506e72f2 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -15,7 +15,7 @@ #include "vkcv/PipelineConfig.hpp" #include "CommandResources.hpp" #include "SyncResources.hpp" -#include "vkcv/Queues.hpp" +#include "vkcv/QueueManager.hpp" namespace vkcv { @@ -36,7 +36,7 @@ namespace vkcv * @param context encapsulates various Vulkan objects */ Core(Context &&context, const Window &window, SwapChain swapChain, std::vector<vk::ImageView> imageViews, - const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues &queues) noexcept; + const CommandResources& commandResources, const SyncResources& syncResources, const QueueManager &queues) noexcept; // explicit destruction of default constructor Core() = delete; @@ -53,7 +53,7 @@ namespace vkcv std::unique_ptr<PipelineManager> m_PipelineManager; CommandResources m_CommandResources; SyncResources m_SyncResources; - VulkanQueues m_Queues; + QueueManager m_QueueManager; uint32_t m_currentSwapchainImageIndex; std::vector<vk::Framebuffer> m_TemporaryFramebuffers; public: diff --git a/include/vkcv/QueueManager.hpp b/include/vkcv/QueueManager.hpp new file mode 100644 index 00000000..1779fb66 --- /dev/null +++ b/include/vkcv/QueueManager.hpp @@ -0,0 +1,36 @@ +#pragma once +#include <vulkan/vulkan.hpp> + +namespace vkcv { + class QueueManager { + public: + static QueueManager create(vk::Device device, + std::vector<std::pair<int, int>> &queuePairsGraphics, + std::vector<std::pair<int, int>> &queuePairsCompute, + std::vector<std::pair<int, int>> &queuePairsTransfer); + + const vk::Queue &getPresentQueue() const; + + const std::vector<vk::Queue> &getGraphicsQueues() const; + + const std::vector<vk::Queue> &getComputeQueues() const; + + const std::vector<vk::Queue> &getTransferQueues() const; + + static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, + std::vector<float> &queuePriorities, + std::vector<vk::QueueFlagBits> &queueFlags, + std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, + std::vector<std::pair<int, int>> &queuePairsGraphics, + std::vector<std::pair<int, int>> &queuePairsCompute, + std::vector<std::pair<int, int>> &queuePairsTransfer); + + private: + vk::Queue m_presentQueue; + std::vector<vk::Queue> m_graphicsQueues; + std::vector<vk::Queue> m_computeQueues; + std::vector<vk::Queue> m_transferQueues; + + QueueManager(std::vector<vk::Queue> graphicsQueues, std::vector<vk::Queue> computeQueues, std::vector<vk::Queue> transferQueues, vk::Queue presentQueue); + }; +} diff --git a/include/vkcv/Queues.hpp b/include/vkcv/Queues.hpp deleted file mode 100644 index c1cca709..00000000 --- a/include/vkcv/Queues.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include <vulkan/vulkan.hpp> - -namespace vkcv { - struct VulkanQueues { - vk::Queue graphicsQueue; - vk::Queue computeQueue; - vk::Queue transferQueue; - vk::Queue presentQueue; - }; - - struct QueueFamilyIndices { - int graphicsIndex = -1; - int computeIndex = -1; - int transferIndex = -1; - int presentIndex = -1; - }; - - VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices); - - QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface); - - // TODO: try to use specialised queues - std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices, - std::vector<float> *outQueuePriorities); - -} diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 9cc5da70..7e6d87ca 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -82,141 +82,6 @@ namespace vkcv return phyDevice; } - - /** - * Given the @p physicalDevice and the @p queuePriorities, the @p queueCreateInfos are computed. First, the requested - * queues are sorted by priority depending on the availability of queues in the queue families of the given - * @p physicalDevice. Then check, if all requested queues are creatable. If so, the @p queueCreateInfos will be computed. - * Furthermore, lists of index pairs (queueFamilyIndex, queueIndex) for later referencing of the separate queues will - * be computed. - * @param[in] physicalDevice The physical device - * @param[in] queuePriorities The queue priorities used for the computation of @p queueCreateInfos - * @param[in] queueFlags The queue flags requesting the queues - * @param[in,out] queueCreateInfos The queue create info structures to be created - * @param[in,out] queuePairsGraphics The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eGraphics - * @param[in,out] queuePairsCompute The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eCompute - * @param[in,out] queuePairsTransfer The list of index pairs (queueFamilyIndex, queueIndex) of queues of type - * vk::QueueFlagBits::eTransfer - * @throws std::runtime_error If the requested queues from @p queueFlags are not creatable due to insufficient availability. - */ - void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, - std::vector<float> &queuePriorities, - std::vector<vk::QueueFlagBits> &queueFlags, - std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, - std::vector<std::pair<int, int>> &queuePairsGraphics, - std::vector<std::pair<int, int>> &queuePairsCompute, - std::vector<std::pair<int, int>> &queuePairsTransfer) - { - queueCreateInfos = {}; - queuePairsGraphics = {}; - queuePairsCompute = {}; - queuePairsTransfer = {}; - std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties(); - - //check priorities of flags -> the lower prioCount the higher the priority - std::vector<int> prios; - for(auto flag: queueFlags){ - int prioCount = 0; - for (int i = 0; i < qFamilyProperties.size(); i++) { - prioCount += (static_cast<uint32_t>(flag & qFamilyProperties[i].queueFlags) != 0) * qFamilyProperties[i].queueCount; - } - prios.push_back(prioCount); - } - //resort flags with heighest priority before allocating the queues - std::vector<vk::QueueFlagBits> newFlags; - for(int i = 0; i < prios.size(); i++){ - auto minElem = std::min_element(prios.begin(), prios.end()); - int index = minElem - prios.begin(); - newFlags.push_back(queueFlags[index]); - prios[index] = std::numeric_limits<int>::max(); - } - - // create requested queues and check if more requested queues are supported - // herefore: create vector that updates available queues in each queue family - // structure: [qFamily_0, ..., qFamily_n] where - // - qFamily_i = [GraphicsCount, ComputeCount, TransferCount], 0 <= i <= n - std::vector<std::vector<int>> queueFamilyStatus, initialQueueFamilyStatus; - - for (auto qFamily : qFamilyProperties) { - int graphicsCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0) * qFamily.queueCount; - int computeCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0) * qFamily.queueCount; - int transferCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0) * qFamily.queueCount; - queueFamilyStatus.push_back({graphicsCount, computeCount, transferCount}); - } - - initialQueueFamilyStatus = queueFamilyStatus; - // check if every queue with the specified queue flag can be created - // this automatically checks for queue flag support! - for (auto qFlag : newFlags) { - bool found; - switch (qFlag) { - case vk::QueueFlagBits::eGraphics: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][0] > 0) { - queuePairsGraphics.push_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many graphics queues were requested than being available!"); - } - break; - case vk::QueueFlagBits::eCompute: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][1] > 0) { - queuePairsCompute.push_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many compute queues were requested than being available!"); - } - break; - case vk::QueueFlagBits::eTransfer: - found = false; - for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][2] > 0) { - queuePairsTransfer.push_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - throw std::runtime_error("Too many transfer queues were requested than being available!"); - } - break; - default: - throw std::runtime_error("Invalid input for queue flag bits. Valid inputs are 'vk::QueueFlagBits::eGraphics', 'vk::QueueFlagBits::eCompute' and 'vk::QueueFlagBits::eTransfer'."); - } - } - - // create all requested queues - for (int i = 0; i < qFamilyProperties.size(); i++) { - uint32_t create = std::abs(initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]); - if (create > 0) { - vk::DeviceQueueCreateInfo qCreateInfo( - vk::DeviceQueueCreateFlags(), - i, - create, - queuePriorities.data() - ); - queueCreateInfos.push_back(qCreateInfo); - } - } - } - /** * @brief With the help of the reference "supported" all elements in "check" checked, * if they are supported by the physical device. @@ -338,9 +203,13 @@ namespace vkcv } const vk::SurfaceKHR surface = createSurface(window.getWindow(), instance, physicalDevice); - const QueueFamilyIndices queueFamilyIndices = getQueueFamilyIndices(physicalDevice, surface); - std::vector<float> queuePriorities; - const std::vector<vk::DeviceQueueCreateInfo> qCreateInfos = createDeviceQueueCreateInfo(queueFamilyIndices, &queuePriorities); + std::vector<vk::DeviceQueueCreateInfo> qCreateInfos; + + // create required queues + std::vector<float> qPriorities; + qPriorities.resize(queueFlags.size(), 1.f); + std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer; + QueueManager::queueCreateInfosQueueHandles(physicalDevice, qPriorities, queueFlags, qCreateInfos, queuePairsGraphics, queuePairsCompute, queuePairsTransfer); vk::DeviceCreateInfo deviceCreateInfo( vk::DeviceCreateFlags(), @@ -353,17 +222,21 @@ namespace vkcv nullptr // Should our device use some features??? If yes: TODO ); - - #ifndef NDEBUG deviceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size()); deviceCreateInfo.ppEnabledLayerNames = validationLayers.data(); #endif + // Ablauf + // qCreateInfos erstellen --> braucht das Device + // device erstellen + // jetzt koennen wir mit dem device die queues erstellen + vk::Device device = physicalDevice.createDevice(deviceCreateInfo); - Context context(instance, physicalDevice, device); - const VulkanQueues queues = getDeviceQueues(device, queueFamilyIndices); + QueueManager queueManager = QueueManager::create(device, queuePairsGraphics, queuePairsCompute, queuePairsTransfer); + + Context context (instance, physicalDevice, device); SwapChain swapChain = SwapChain::create(window, context, surface); @@ -390,14 +263,14 @@ namespace vkcv subResourceRange ); - imageViews.push_back( device.createImageView( imageViewCreateInfo ) ); + imageViews.push_back( device.createImageView( imageViewCreateInfo )); } - const int graphicQueueFamilyIndex = queueFamilyIndices.graphicsIndex; + const int graphicQueueFamilyIndex = queuePairsGraphics[0].first; const auto defaultCommandResources = createDefaultCommandResources(context.getDevice(), graphicQueueFamilyIndex); const auto defaultSyncResources = createDefaultSyncResources(context.getDevice()); - return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queues); + return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources, queueManager); } const Context &Core::getContext() const @@ -406,16 +279,16 @@ namespace vkcv } Core::Core(Context &&context, const Window &window , SwapChain swapChain, std::vector<vk::ImageView> imageViews, - const CommandResources& commandResources, const SyncResources& syncResources, const VulkanQueues& queues) noexcept : - m_Context(std::move(context)), - m_window(window), - m_swapchain(swapChain), - m_swapchainImageViews(imageViews), - m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, - m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, - m_CommandResources(commandResources), - m_SyncResources(syncResources), - m_Queues(queues) + const CommandResources& commandResources, const SyncResources& syncResources, const QueueManager& queueManager) noexcept : + m_Context(std::move(context)), + m_window(window), + m_swapchain(swapChain), + m_swapchainImageViews(imageViews), + m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)}, + m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, + m_CommandResources(commandResources), + m_SyncResources(syncResources), + m_QueueManager(queueManager) {} Core::~Core() noexcept { @@ -515,13 +388,13 @@ namespace vkcv m_CommandResources.commandBuffer.end(); const vk::SubmitInfo submitInfo(0, nullptr, 0, 1, &(m_CommandResources.commandBuffer), 1, &m_SyncResources.renderFinished); - m_Queues.graphicsQueue.submit(submitInfo); + m_QueueManager.getGraphicsQueues()[0].submit(submitInfo); vk::Result presentResult; const vk::SwapchainKHR& swapchain = m_swapchain.getSwapchain(); const vk::PresentInfoKHR presentInfo(1, &m_SyncResources.renderFinished, 1, &swapchain, &m_currentSwapchainImageIndex, &presentResult); - m_Queues.presentQueue.presentKHR(presentInfo); + m_QueueManager.getPresentQueue().presentKHR(presentInfo); if (presentResult != vk::Result::eSuccess) { std::cout << "Error: swapchain present failed" << std::endl; } diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp new file mode 100644 index 00000000..c6c9dda4 --- /dev/null +++ b/src/vkcv/QueueManager.cpp @@ -0,0 +1,189 @@ +#include "vkcv/QueueManager.hpp" +#include <unordered_set> + +namespace vkcv { + + /** + * Given the @p physicalDevice and the @p queuePriorities, the @p queueCreateInfos are computed. First, the requested + * queues are sorted by priority depending on the availability of queues in the queue families of the given + * @p physicalDevice. Then check, if all requested queues are creatable. If so, the @p queueCreateInfos will be computed. + * Furthermore, lists of index pairs (queueFamilyIndex, queueIndex) for later referencing of the separate queues will + * be computed. + * @param[in] physicalDevice The physical device + * @param[in] queuePriorities The queue priorities used for the computation of @p queueCreateInfos + * @param[in] queueFlags The queue flags requesting the queues + * @param[in,out] queueCreateInfos The queue create info structures to be created + * @param[in,out] queuePairsGraphics The list of index pairs (queueFamilyIndex, queueIndex) of queues of type + * vk::QueueFlagBits::eGraphics + * @param[in,out] queuePairsCompute The list of index pairs (queueFamilyIndex, queueIndex) of queues of type + * vk::QueueFlagBits::eCompute + * @param[in,out] queuePairsTransfer The list of index pairs (queueFamilyIndex, queueIndex) of queues of type + * vk::QueueFlagBits::eTransfer + * @throws std::runtime_error If the requested queues from @p queueFlags are not creatable due to insufficient availability. + */ + void QueueManager::queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, + std::vector<float> &queuePriorities, + std::vector<vk::QueueFlagBits> &queueFlags, + std::vector<vk::DeviceQueueCreateInfo> &queueCreateInfos, + std::vector<std::pair<int, int>> &queuePairsGraphics, + std::vector<std::pair<int, int>> &queuePairsCompute, + std::vector<std::pair<int, int>> &queuePairsTransfer) + { + queueCreateInfos = {}; + queuePairsGraphics = {}; + queuePairsCompute = {}; + queuePairsTransfer = {}; + std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties(); + + //check priorities of flags -> the lower prioCount the higher the priority + std::vector<int> prios; + for(auto flag: queueFlags) { + int prioCount = 0; + for (int i = 0; i < qFamilyProperties.size(); i++) { + prioCount += (static_cast<uint32_t>(flag & qFamilyProperties[i].queueFlags) != 0) * qFamilyProperties[i].queueCount; + } + prios.push_back(prioCount); + } + //resort flags with heighest priority before allocating the queues + std::vector<vk::QueueFlagBits> newFlags; + for(int i = 0; i < prios.size(); i++) { + auto minElem = std::min_element(prios.begin(), prios.end()); + int index = minElem - prios.begin(); + newFlags.push_back(queueFlags[index]); + prios[index] = std::numeric_limits<int>::max(); + } + + // create requested queues and check if more requested queues are supported + // herefore: create vector that updates available queues in each queue family + // structure: [qFamily_0, ..., qFamily_n] where + // - qFamily_i = [GraphicsCount, ComputeCount, TransferCount], 0 <= i <= n + std::vector<std::vector<int>> queueFamilyStatus, initialQueueFamilyStatus; + + for (auto qFamily : qFamilyProperties) { + int graphicsCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0) * qFamily.queueCount; + int computeCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0) * qFamily.queueCount; + int transferCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0) * qFamily.queueCount; + queueFamilyStatus.push_back({graphicsCount, computeCount, transferCount}); + } + + initialQueueFamilyStatus = queueFamilyStatus; + // check if every queue with the specified queue flag can be created + // this automatically checks for queue flag support! + for (auto qFlag : newFlags) { + bool found; + switch (qFlag) { + case vk::QueueFlagBits::eGraphics: + found = false; + for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][0] > 0) { + queuePairsGraphics.push_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + throw std::runtime_error("Too many graphics queues were requested than being available!"); + } + break; + case vk::QueueFlagBits::eCompute: + found = false; + for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][1] > 0) { + queuePairsCompute.push_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + throw std::runtime_error("Too many compute queues were requested than being available!"); + } + break; + case vk::QueueFlagBits::eTransfer: + found = false; + for (int i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][2] > 0) { + queuePairsTransfer.push_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + throw std::runtime_error("Too many transfer queues were requested than being available!"); + } + break; + default: + throw std::runtime_error("Invalid input for queue flag bits. Valid inputs are 'vk::QueueFlagBits::eGraphics', 'vk::QueueFlagBits::eCompute' and 'vk::QueueFlagBits::eTransfer'."); + } + } + + // create all requested queues + for (int i = 0; i < qFamilyProperties.size(); i++) { + uint32_t create = std::abs(initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0]); + if (create > 0) { + vk::DeviceQueueCreateInfo qCreateInfo( + vk::DeviceQueueCreateFlags(), + i, + create, + queuePriorities.data() + ); + queueCreateInfos.push_back(qCreateInfo); + } + } + } + + /** + * Computes the queue handles from @p queuePairs + * @param device The device + * @param queuePairs The queuePairs that were created separately for each queue type (e.g., vk::QueueFlagBits::eGraphics) + * @return An array of queue handles based on the @p queuePairs + */ + std::vector<vk::Queue> getQueueHandles(const vk::Device device, const std::vector<std::pair<int, int>> queuePairs) { + std::vector<vk::Queue> queueHandles; + for (auto q : queuePairs) { + int queueFamilyIndex = q.first; // the queueIndex of the queue family + int queueIndex = q.second; // the queueIndex within a queue family + queueHandles.push_back(device.getQueue(queueFamilyIndex, queueIndex)); + } + return queueHandles; + } + + + QueueManager QueueManager::create(vk::Device device, + std::vector<std::pair<int, int>> &queuePairsGraphics, + std::vector<std::pair<int, int>> &queuePairsCompute, + std::vector<std::pair<int, int>> &queuePairsTransfer) { + + std::vector<vk::Queue> graphicsQueues = getQueueHandles(device, queuePairsGraphics); + std::vector<vk::Queue> computeQueues = getQueueHandles(device, queuePairsCompute ); + std::vector<vk::Queue> transferQueues = getQueueHandles(device, queuePairsTransfer); + + return QueueManager( graphicsQueues, computeQueues, transferQueues, graphicsQueues[0]); + } + + QueueManager::QueueManager(std::vector<vk::Queue> graphicsQueues, std::vector<vk::Queue> computeQueues, std::vector<vk::Queue> transferQueues, vk::Queue presentQueue) + : m_graphicsQueues(graphicsQueues), m_computeQueues(computeQueues), m_transferQueues(transferQueues), m_presentQueue(presentQueue) + {} + + const vk::Queue &QueueManager::getPresentQueue() const { + return m_presentQueue; + } + + const std::vector<vk::Queue> &QueueManager::getGraphicsQueues() const { + return m_graphicsQueues; + } + + const std::vector<vk::Queue> &QueueManager::getComputeQueues() const { + return m_computeQueues; + } + + const std::vector<vk::Queue> &QueueManager::getTransferQueues() const { + return m_transferQueues; + } + +} \ No newline at end of file diff --git a/src/vkcv/Queues.cpp b/src/vkcv/Queues.cpp deleted file mode 100644 index 49e992ff..00000000 --- a/src/vkcv/Queues.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "vkcv/Queues.hpp" -#include <unordered_set> - -namespace vkcv { - - VulkanQueues getDeviceQueues(const vk::Device& device, const QueueFamilyIndices& familyIndices) { - VulkanQueues queues; - queues.graphicsQueue = device.getQueue(familyIndices.graphicsIndex, 0); - queues.computeQueue = device.getQueue(familyIndices.computeIndex, 0); - queues.transferQueue = device.getQueue(familyIndices.transferIndex, 0); - queues.presentQueue = device.getQueue(familyIndices.presentIndex, 0); - return queues; - } - - QueueFamilyIndices getQueueFamilyIndices(const vk::PhysicalDevice& physicalDevice, const vk::SurfaceKHR surface) { - const std::vector<vk::QueueFamilyProperties> familyProps = physicalDevice.getQueueFamilyProperties(); - - QueueFamilyIndices indices; - - for (int i = 0; i < familyProps.size(); i++) { - const auto& property = familyProps[i]; - - const bool hasQueues = property.queueCount >= 1; - if (!hasQueues) { - continue; - } - - if (property.queueFlags & vk::QueueFlagBits::eGraphics) { - indices.graphicsIndex = i; - } - if (property.queueFlags & vk::QueueFlagBits::eCompute) { - indices.computeIndex = i; - } - if (property.queueFlags & vk::QueueFlagBits::eTransfer) { - indices.transferIndex = i; - } - if (physicalDevice.getSurfaceSupportKHR(i, surface)) { - indices.presentIndex = i; - } - } - assert(indices.graphicsIndex != -1); - assert(indices.computeIndex != -1); - assert(indices.transferIndex != -1); - assert(indices.presentIndex != -1); - return indices; - } - - std::vector<vk::DeviceQueueCreateInfo> createDeviceQueueCreateInfo(const QueueFamilyIndices& indices, - std::vector<float>* outQueuePriorities) { - - // use set to avoid duplicate queues - std::unordered_set<int> familyIndexSet; - familyIndexSet.insert(indices.graphicsIndex); - familyIndexSet.insert(indices.computeIndex); - familyIndexSet.insert(indices.transferIndex); - familyIndexSet.insert(indices.presentIndex); - - const vk::DeviceQueueCreateFlagBits flags = {}; - std::vector<vk::DeviceQueueCreateInfo> createInfos; - - outQueuePriorities->resize(familyIndexSet.size(), 1.f); - int priorityIndex = 0; - - for (const auto index : familyIndexSet) { - const vk::DeviceQueueCreateInfo graphicsCreateInfo(flags, index, 1, &outQueuePriorities->at(priorityIndex)); - createInfos.push_back(graphicsCreateInfo); - priorityIndex++; - } - return createInfos; - } -} \ No newline at end of file -- GitLab