From 200c03e60110ce4296c6880cf988c7ea46324213 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Sun, 22 May 2022 23:22:26 +0200 Subject: [PATCH] Adjusted doxygen comments of queue manager Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- include/vkcv/QueueManager.hpp | 88 ++++++++--------- src/vkcv/Context.cpp | 170 ++++++++++++++++++++++++++++++++- src/vkcv/QueueManager.cpp | 172 +--------------------------------- 3 files changed, 212 insertions(+), 218 deletions(-) diff --git a/include/vkcv/QueueManager.hpp b/include/vkcv/QueueManager.hpp index f05a1007..163021e6 100644 --- a/include/vkcv/QueueManager.hpp +++ b/include/vkcv/QueueManager.hpp @@ -35,78 +35,63 @@ namespace vkcv { class QueueManager { public: /** - * Creates a QueueManager with the given queue pairs - * @param device device that holds the queues that are specified in the queue pairs - * @param queuePairsGraphics graphic queue pairs of queueFamily and queueIndex - * @param queuePairsCompute compute queue pairs of queueFamily and queueIndex - * @param queuePairsTransfer transfer queue pairs of queueFamily and queueIndex - * @return a QueueManager with the specified queuePairs + * @brief Creates a queue manager with the given pairs of queues. + * + * @param[in,out] device Vulkan device that holds the queues + * @param[in] queuePairsGraphics Graphic queue pairs of queueFamily and queueIndex + * @param[in] queuePairsCompute Compute queue pairs of queueFamily and queueIndex + * @param[in] queuePairsTransfer Transfer queue pairs of queueFamily and queueIndex + * @return New queue manager with the specified queue pairs */ 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 std::vector<std::pair<int, int>> &queuePairsGraphics, + const std::vector<std::pair<int, int>> &queuePairsCompute, + const std::vector<std::pair<int, int>> &queuePairsTransfer); + /** - * Returns the default presentQueue. Recommended to use the presentQueue in the Swapchain - * @return a default presentQueue + * @brief Returns the default queue with present support. + * Recommended to use the present queue in the swapchain. + * + * @return Default present queue */ [[nodiscard]] const Queue &getPresentQueue() const; /** - * Returns all queues with the graphics flag - * @return vector of graphic queues + * @brief Returns all queues with the graphics flag. + * + * @return Vector of graphics queues */ [[nodiscard]] const std::vector<Queue> &getGraphicsQueues() const; /** - * Returns all queues with the compute flag - * @return vector of compute queues + * @brief Returns all queues with the compute flag. + * + * @return Vector of compute queues */ [[nodiscard]] const std::vector<Queue> &getComputeQueues() const; /** - * Returns all queues with the transfer flag - * @return vector of transfer queues + * @brief Returns all queues with the transfer flag. + * + * @return Vector of transfer queues */ [[nodiscard]] const std::vector<Queue> &getTransferQueues() const; - - /** - * 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. - */ - static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, - const std::vector<float> &queuePriorities, - const 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); - + /** - * Checks for surface support in the queues - * @param physicalDevice to get the Queues - * @param surface that needs to checked - * @return + * @brief Checks for presenting support of a given surface + * in the queues and returns the queue family index of the + * supporting queue. + * + * @param[in] physicalDevice Vulkan physical device + * @param[in] surface Surface + * @return Queue family index of the supporting present queue */ - static uint32_t checkSurfaceSupport(const vk::PhysicalDevice &physicalDevice, vk::SurfaceKHR &surface); + static uint32_t checkSurfaceSupport(const vk::PhysicalDevice &physicalDevice, + const vk::SurfaceKHR &surface); private: std::vector<Queue> m_graphicsQueues; @@ -115,6 +100,9 @@ namespace vkcv { size_t m_presentIndex; - QueueManager(std::vector<Queue>&& graphicsQueues, std::vector<Queue>&& computeQueues, std::vector<Queue>&& transferQueues, size_t presentIndex); + QueueManager(std::vector<Queue>&& graphicsQueues, + std::vector<Queue>&& computeQueues, + std::vector<Queue>&& transferQueues, + size_t presentIndex); }; } diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index 8988e479..f6358c41 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -185,6 +185,166 @@ namespace vkcv return extensions; } + + /** + * 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. + */ + static void queueCreateInfosQueueHandles(vk::PhysicalDevice &physicalDevice, + const std::vector<float> &queuePriorities, + const 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 (size_t 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(size_t 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) { + auto graphicsCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0? qFamily.queueCount : 0; + auto computeCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0? qFamily.queueCount : 0; + auto transferCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0? qFamily.queueCount : 0; + queueFamilyStatus.push_back({ + static_cast<int>(graphicsCount), + static_cast<int>(computeCount), + static_cast<int>(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 (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][0] > 0) { + queuePairsGraphics.emplace_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (initialQueueFamilyStatus[i][0] > 0) { + queuePairsGraphics.emplace_back(std::pair(i, 0)); + found = true; + } + } + + vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); + } + break; + case vk::QueueFlagBits::eCompute: + found = false; + for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][1] > 0) { + queuePairsCompute.emplace_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (initialQueueFamilyStatus[i][1] > 0) { + queuePairsCompute.emplace_back(std::pair(i, 0)); + found = true; + } + } + + vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); + } + break; + case vk::QueueFlagBits::eTransfer: + found = false; + for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (queueFamilyStatus[i][2] > 0) { + queuePairsTransfer.emplace_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2])); + queueFamilyStatus[i][0]--; + queueFamilyStatus[i][1]--; + queueFamilyStatus[i][2]--; + found = true; + } + } + if (!found) { + for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { + if (initialQueueFamilyStatus[i][2] > 0) { + queuePairsTransfer.emplace_back(std::pair(i, 0)); + found = true; + } + } + + vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); + } + break; + default: + vkcv_log(LogLevel::ERROR, "Invalid input for queue flag bits: %s", vk::to_string(qFlag).c_str()); + break; + } + } + + // create all requested queues + for (size_t 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); + } + } + } Context Context::create(const char *applicationName, uint32_t applicationVersion, @@ -306,7 +466,15 @@ namespace vkcv qPriorities.resize(queueFlags.size(), 1.f); std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer; - QueueManager::queueCreateInfosQueueHandles(physicalDevice, qPriorities, queueFlags, qCreateInfos, queuePairsGraphics, queuePairsCompute, queuePairsTransfer); + queueCreateInfosQueueHandles( + physicalDevice, + qPriorities, + queueFlags, + qCreateInfos, + queuePairsGraphics, + queuePairsCompute, + queuePairsTransfer + ); vk::DeviceCreateInfo deviceCreateInfo( vk::DeviceCreateFlags(), diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp index ff134041..d2a4d593 100644 --- a/src/vkcv/QueueManager.cpp +++ b/src/vkcv/QueueManager.cpp @@ -9,166 +9,6 @@ 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, - const std::vector<float> &queuePriorities, - const 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 (size_t 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(size_t 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) { - auto graphicsCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0? qFamily.queueCount : 0; - auto computeCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0? qFamily.queueCount : 0; - auto transferCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0? qFamily.queueCount : 0; - queueFamilyStatus.push_back({ - static_cast<int>(graphicsCount), - static_cast<int>(computeCount), - static_cast<int>(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 (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][0] > 0) { - queuePairsGraphics.emplace_back(std::pair(i, initialQueueFamilyStatus[i][0] - queueFamilyStatus[i][0])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (initialQueueFamilyStatus[i][0] > 0) { - queuePairsGraphics.emplace_back(std::pair(i, 0)); - found = true; - } - } - - vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); - } - break; - case vk::QueueFlagBits::eCompute: - found = false; - for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][1] > 0) { - queuePairsCompute.emplace_back(std::pair(i, initialQueueFamilyStatus[i][1] - queueFamilyStatus[i][1])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (initialQueueFamilyStatus[i][1] > 0) { - queuePairsCompute.emplace_back(std::pair(i, 0)); - found = true; - } - } - - vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); - } - break; - case vk::QueueFlagBits::eTransfer: - found = false; - for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (queueFamilyStatus[i][2] > 0) { - queuePairsTransfer.emplace_back(std::pair(i, initialQueueFamilyStatus[i][2] - queueFamilyStatus[i][2])); - queueFamilyStatus[i][0]--; - queueFamilyStatus[i][1]--; - queueFamilyStatus[i][2]--; - found = true; - } - } - if (!found) { - for (size_t i = 0; i < queueFamilyStatus.size() && !found; i++) { - if (initialQueueFamilyStatus[i][2] > 0) { - queuePairsTransfer.emplace_back(std::pair(i, 0)); - found = true; - } - } - - vkcv_log(LogLevel::WARNING, "Not enough %s queues", vk::to_string(qFlag).c_str()); - } - break; - default: - vkcv_log(LogLevel::ERROR, "Invalid input for queue flag bits: %s", vk::to_string(qFlag).c_str()); - break; - } - } - - // create all requested queues - for (size_t 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 @@ -190,9 +30,9 @@ namespace vkcv { 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) { + const std::vector<std::pair<int, int>> &queuePairsGraphics, + const std::vector<std::pair<int, int>> &queuePairsCompute, + const std::vector<std::pair<int, int>> &queuePairsTransfer) { std::vector<Queue> graphicsQueues = getQueues(device, queuePairsGraphics); std::vector<Queue> computeQueues = getQueues(device, queuePairsCompute); @@ -201,10 +41,8 @@ namespace vkcv { return QueueManager( std::move(graphicsQueues), std::move(computeQueues), std::move(transferQueues), 0); } - uint32_t QueueManager::checkSurfaceSupport( - const vk::PhysicalDevice &physicalDevice, - vk::SurfaceKHR &surface - ) { + uint32_t QueueManager::checkSurfaceSupport(const vk::PhysicalDevice &physicalDevice, + const vk::SurfaceKHR &surface) { std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties(); for(uint32_t i = 0; i < qFamilyProperties.size(); i++) { -- GitLab