Skip to content
Snippets Groups Projects
Verified Commit 200c03e6 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Adjusted doxygen comments of queue manager

parent 89f60c8d
No related branches found
No related tags found
1 merge request!97Resolve "Dokumentation vervollständigen"
...@@ -35,78 +35,63 @@ namespace vkcv { ...@@ -35,78 +35,63 @@ namespace vkcv {
class QueueManager { class QueueManager {
public: public:
/** /**
* Creates a QueueManager with the given queue pairs * @brief Creates a queue manager with the given pairs of queues.
* @param device device that holds the queues that are specified in the queue pairs *
* @param queuePairsGraphics graphic queue pairs of queueFamily and queueIndex * @param[in,out] device Vulkan device that holds the queues
* @param queuePairsCompute compute queue pairs of queueFamily and queueIndex * @param[in] queuePairsGraphics Graphic queue pairs of queueFamily and queueIndex
* @param queuePairsTransfer transfer queue pairs of queueFamily and queueIndex * @param[in] queuePairsCompute Compute queue pairs of queueFamily and queueIndex
* @return a QueueManager with the specified queuePairs * @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, static QueueManager create(vk::Device device,
std::vector<std::pair<int, int>> &queuePairsGraphics, const std::vector<std::pair<int, int>> &queuePairsGraphics,
std::vector<std::pair<int, int>> &queuePairsCompute, const std::vector<std::pair<int, int>> &queuePairsCompute,
std::vector<std::pair<int, int>> &queuePairsTransfer); const std::vector<std::pair<int, int>> &queuePairsTransfer);
/** /**
* Returns the default presentQueue. Recommended to use the presentQueue in the Swapchain * @brief Returns the default queue with present support.
* @return a default presentQueue * Recommended to use the present queue in the swapchain.
*
* @return Default present queue
*/ */
[[nodiscard]] [[nodiscard]]
const Queue &getPresentQueue() const; const Queue &getPresentQueue() const;
/** /**
* Returns all queues with the graphics flag * @brief Returns all queues with the graphics flag.
* @return vector of graphic queues *
* @return Vector of graphics queues
*/ */
[[nodiscard]] [[nodiscard]]
const std::vector<Queue> &getGraphicsQueues() const; const std::vector<Queue> &getGraphicsQueues() const;
/** /**
* Returns all queues with the compute flag * @brief Returns all queues with the compute flag.
* @return vector of compute queues *
* @return Vector of compute queues
*/ */
[[nodiscard]] [[nodiscard]]
const std::vector<Queue> &getComputeQueues() const; const std::vector<Queue> &getComputeQueues() const;
/** /**
* Returns all queues with the transfer flag * @brief Returns all queues with the transfer flag.
* @return vector of transfer queues *
* @return Vector of transfer queues
*/ */
[[nodiscard]] [[nodiscard]]
const std::vector<Queue> &getTransferQueues() const; 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 * @brief Checks for presenting support of a given surface
* @param physicalDevice to get the Queues * in the queues and returns the queue family index of the
* @param surface that needs to checked * supporting queue.
* @return *
* @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: private:
std::vector<Queue> m_graphicsQueues; std::vector<Queue> m_graphicsQueues;
...@@ -115,6 +100,9 @@ namespace vkcv { ...@@ -115,6 +100,9 @@ namespace vkcv {
size_t m_presentIndex; 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);
}; };
} }
...@@ -185,6 +185,166 @@ namespace vkcv ...@@ -185,6 +185,166 @@ namespace vkcv
return extensions; 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, Context Context::create(const char *applicationName,
uint32_t applicationVersion, uint32_t applicationVersion,
...@@ -306,7 +466,15 @@ namespace vkcv ...@@ -306,7 +466,15 @@ namespace vkcv
qPriorities.resize(queueFlags.size(), 1.f); qPriorities.resize(queueFlags.size(), 1.f);
std::vector<std::pair<int, int>> queuePairsGraphics, queuePairsCompute, queuePairsTransfer; 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::DeviceCreateInfo deviceCreateInfo(
vk::DeviceCreateFlags(), vk::DeviceCreateFlags(),
......
...@@ -9,166 +9,6 @@ ...@@ -9,166 +9,6 @@
namespace vkcv { 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 * Computes the queue handles from @p queuePairs
* @param device The device * @param device The device
...@@ -190,9 +30,9 @@ namespace vkcv { ...@@ -190,9 +30,9 @@ namespace vkcv {
QueueManager QueueManager::create(vk::Device device, QueueManager QueueManager::create(vk::Device device,
std::vector<std::pair<int, int>> &queuePairsGraphics, const std::vector<std::pair<int, int>> &queuePairsGraphics,
std::vector<std::pair<int, int>> &queuePairsCompute, const std::vector<std::pair<int, int>> &queuePairsCompute,
std::vector<std::pair<int, int>> &queuePairsTransfer) { const std::vector<std::pair<int, int>> &queuePairsTransfer) {
std::vector<Queue> graphicsQueues = getQueues(device, queuePairsGraphics); std::vector<Queue> graphicsQueues = getQueues(device, queuePairsGraphics);
std::vector<Queue> computeQueues = getQueues(device, queuePairsCompute); std::vector<Queue> computeQueues = getQueues(device, queuePairsCompute);
...@@ -201,10 +41,8 @@ namespace vkcv { ...@@ -201,10 +41,8 @@ namespace vkcv {
return QueueManager( std::move(graphicsQueues), std::move(computeQueues), std::move(transferQueues), 0); return QueueManager( std::move(graphicsQueues), std::move(computeQueues), std::move(transferQueues), 0);
} }
uint32_t QueueManager::checkSurfaceSupport( uint32_t QueueManager::checkSurfaceSupport(const vk::PhysicalDevice &physicalDevice,
const vk::PhysicalDevice &physicalDevice, const vk::SurfaceKHR &surface) {
vk::SurfaceKHR &surface
) {
std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties(); std::vector<vk::QueueFamilyProperties> qFamilyProperties = physicalDevice.getQueueFamilyProperties();
for(uint32_t i = 0; i < qFamilyProperties.size(); i++) { for(uint32_t i = 0; i < qFamilyProperties.size(); i++) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment