Made it possible to specify the desired queue priorities.

If none are provided, it will use 1.0f for everything.
This commit is contained in:
Charles Giessen 2020-02-06 16:56:50 -07:00
parent 8b33c46bf9
commit 4a464a61aa
2 changed files with 111 additions and 34 deletions

View File

@ -560,11 +560,11 @@ PhysicalDeviceSelector::Suitable PhysicalDeviceSelector::is_device_suitable (VkP
VkPhysicalDeviceProperties device_properties;
vkGetPhysicalDeviceProperties (phys_device, &device_properties);
if ((criteria.preferred_type == PreferredDevice::discrete &&
if ((criteria.preferred_type == PreferredDeviceType::discrete &&
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
(criteria.preferred_type == PreferredDevice::integrated &&
(criteria.preferred_type == PreferredDeviceType::integrated &&
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) ||
(criteria.preferred_type == PreferredDevice::virtual_gpu &&
(criteria.preferred_type == PreferredDeviceType::virtual_gpu &&
device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) {
if (criteria.allow_fallback)
suitable = Suitable::partial;
@ -598,15 +598,22 @@ detail::Expected<PhysicalDevice, VkResult> PhysicalDeviceSelector::select () {
if (!physical_devices.has_value ()) {
return detail::Error{ physical_devices.error ().error_code, "Failed to find physical devices" };
}
if (physical_devices.value ().size () == 0) {
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "No physical devices found" };
}
PhysicalDevice physical_device;
for (const auto& device : physical_devices.value ()) {
auto suitable = is_device_suitable (device);
if (suitable == Suitable::yes) {
physical_device.phys_device = device;
break;
} else if (suitable == Suitable::partial) {
physical_device.phys_device = device;
if (criteria.use_first_gpu_unconditionally) {
physical_device.phys_device = physical_devices.value ().at (0);
} else {
for (const auto& device : physical_devices.value ()) {
auto suitable = is_device_suitable (device);
if (suitable == Suitable::yes) {
physical_device.phys_device = device;
break;
} else if (suitable == Suitable::partial) {
physical_device.phys_device = device;
}
}
}
@ -638,19 +645,11 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_surface (VkSurfaceKHR surfac
info.headless = false;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_discrete () {
criteria.preferred_type = PreferredDevice::discrete;
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_gpu_device_type (PreferredDeviceType type) {
criteria.preferred_type = type;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_integrated () {
criteria.preferred_type = PreferredDevice::integrated;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_virtual_gpu () {
criteria.preferred_type = PreferredDevice::virtual_gpu;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::allow_fallback (bool fallback) {
PhysicalDeviceSelector& PhysicalDeviceSelector::allow_fallback_gpu (bool fallback) {
criteria.allow_fallback = fallback;
return *this;
}
@ -678,10 +677,20 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension (std::str
criteria.required_extensions.push_back (extension);
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extensions (std::vector<std::string> extensions) {
criteria.required_extensions.insert (
criteria.required_extensions.end (), extensions.begin (), extensions.end ());
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension (std::string extension) {
criteria.desired_extensions.push_back (extension);
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extensions (std::vector<std::string> extensions) {
criteria.desired_extensions.insert (
criteria.desired_extensions.end (), extensions.begin (), extensions.end ());
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version (uint32_t major, uint32_t minor) {
criteria.required_version = VK_MAKE_VERSION (major, minor, 0);
return *this;
@ -694,6 +703,14 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features (VkPhysica
criteria.required_features = features;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::set_desired_features (VkPhysicalDeviceFeatures features) {
criteria.desired_features = features;
return *this;
}
PhysicalDeviceSelector& PhysicalDeviceSelector::select_first_device_unconditionally (bool unconditionally) {
criteria.use_first_gpu_unconditionally = unconditionally;
return *this;
}
// ---- Device ---- //
@ -711,16 +728,33 @@ DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
detail::Expected<Device, VkResult> DeviceBuilder::build () {
auto& queue_properties = info.physical_device.queue_family_properties;
std::vector<QueueFamily> families;
families.push_back ({ queue_properties.graphics, std::vector<float> (queue_properties.count_graphics) });
if (queue_properties.compute != -1 && queue_properties.compute != queue_properties.graphics)
families.push_back ({ queue_properties.compute, std::vector<float> (queue_properties.count_compute) });
families.push_back ({ queue_properties.graphics,
info.graphics_queue_priorities.size () == 0 ?
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_graphics : 1, 1.0f) :
info.graphics_queue_priorities });
if (queue_properties.compute != -1 && queue_properties.compute != queue_properties.graphics) {
families.push_back ({ queue_properties.compute,
info.compute_queue_priorities.size () == 0 ?
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_compute : 1, 1.0f) :
info.compute_queue_priorities });
}
if (queue_properties.transfer != -1 && queue_properties.transfer != queue_properties.graphics &&
queue_properties.transfer != queue_properties.compute)
families.push_back ({ queue_properties.transfer, std::vector<float> (queue_properties.count_transfer) });
families.push_back ({ queue_properties.transfer,
info.transfer_queue_priorities.size () == 0 ?
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_transfer : 1, 1.0f) :
info.transfer_queue_priorities });
if (queue_properties.sparse != -1 && queue_properties.sparse != queue_properties.graphics &&
queue_properties.sparse != queue_properties.compute &&
queue_properties.sparse != queue_properties.transfer)
families.push_back ({ queue_properties.sparse, std::vector<float> (queue_properties.count_sparse) });
families.push_back ({ queue_properties.sparse,
info.sparse_queue_priorities.size () == 0 ?
std::vector<float> (info.use_multiple_queues_per_family ? queue_properties.count_sparse : 1, 1.0f) :
info.sparse_queue_priorities });
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
for (auto& queue : families) {
@ -763,6 +797,31 @@ template <typename T> DeviceBuilder& DeviceBuilder::add_pNext (T* structure) {
info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
return *this;
}
DeviceBuilder& DeviceBuilder::use_multiple_queues_per_family (bool multi_queue) {
info.use_multiple_queues_per_family = true;
return *this;
}
DeviceBuilder& DeviceBuilder::set_graphics_queue_priorities (std::vector<float> priorities) {
if (info.physical_device.queue_family_properties.count_graphics >= priorities.size ())
info.graphics_queue_priorities = priorities;
return *this;
}
DeviceBuilder& DeviceBuilder::set_compute_queue_priorities (std::vector<float> priorities) {
if (info.physical_device.queue_family_properties.count_compute >= priorities.size ())
info.compute_queue_priorities = priorities;
return *this;
}
DeviceBuilder& DeviceBuilder::set_transfer_queue_priorities (std::vector<float> priorities) {
if (info.physical_device.queue_family_properties.count_transfer >= priorities.size ())
info.transfer_queue_priorities = priorities;
return *this;
}
DeviceBuilder& DeviceBuilder::set_sparse_queue_priorities (std::vector<float> priorities) {
if (info.physical_device.queue_family_properties.count_sparse >= priorities.size ())
info.sparse_queue_priorities = priorities;
return *this;
}
// ---- Queue ---- //

View File

@ -236,11 +236,9 @@ struct PhysicalDeviceSelector {
PhysicalDeviceSelector& set_surface (VkSurfaceKHR instance);
PhysicalDeviceSelector& prefer_discrete ();
PhysicalDeviceSelector& prefer_integrated ();
PhysicalDeviceSelector& prefer_virtual_gpu ();
PhysicalDeviceSelector& allow_fallback (bool fallback = true);
enum PreferredDeviceType { discrete, integrated, virtual_gpu, cpu, dont_care };
PhysicalDeviceSelector& prefer_gpu_device_type (PreferredDeviceType type = PreferredDeviceType::discrete);
PhysicalDeviceSelector& allow_fallback_gpu (bool fallback = true);
PhysicalDeviceSelector& require_present (bool require = true);
PhysicalDeviceSelector& require_dedicated_transfer_queue ();
@ -250,12 +248,18 @@ struct PhysicalDeviceSelector {
PhysicalDeviceSelector& desired_device_memory_size (VkDeviceSize size);
PhysicalDeviceSelector& add_required_extension (std::string extension);
PhysicalDeviceSelector& add_required_extensions (std::vector<std::string> extensions);
PhysicalDeviceSelector& add_desired_extension (std::string extension);
PhysicalDeviceSelector& add_desired_extensions (std::vector<std::string> extensions);
PhysicalDeviceSelector& set_desired_version (uint32_t major, uint32_t minor);
PhysicalDeviceSelector& set_minimum_version (uint32_t major = 1, uint32_t minor = 0);
PhysicalDeviceSelector& set_required_features (VkPhysicalDeviceFeatures features);
PhysicalDeviceSelector& set_desired_features (VkPhysicalDeviceFeatures features);
PhysicalDeviceSelector& select_first_device_unconditionally (bool unconditionally = true);
private:
struct PhysicalDeviceInfo {
@ -264,10 +268,8 @@ struct PhysicalDeviceSelector {
bool headless = false;
} info;
enum PreferredDevice { discrete, integrated, virtual_gpu, cpu, dont_care };
struct SelectionCriteria {
PreferredDevice preferred_type = PreferredDevice::discrete;
PreferredDeviceType preferred_type = PreferredDeviceType::discrete;
bool allow_fallback = true;
bool require_present = true;
bool require_dedicated_transfer_queue = false;
@ -284,6 +286,7 @@ struct PhysicalDeviceSelector {
VkPhysicalDeviceFeatures required_features{};
VkPhysicalDeviceFeatures desired_features{};
bool use_first_gpu_unconditionally = false;
} criteria;
enum class Suitable { yes, partial, no };
@ -308,12 +311,27 @@ class DeviceBuilder {
template <typename T> DeviceBuilder& add_pNext (T* structure);
DeviceBuilder& use_multiple_queues_per_family (bool multi_queue = true);
DeviceBuilder& set_graphics_queue_priorities (std::vector<float> priorities);
DeviceBuilder& set_compute_queue_priorities (std::vector<float> priorities);
DeviceBuilder& set_transfer_queue_priorities (std::vector<float> priorities);
DeviceBuilder& set_sparse_queue_priorities (std::vector<float> priorities);
private:
struct DeviceInfo {
VkDeviceCreateFlags flags;
std::vector<VkBaseOutStructure*> pNext_chain;
PhysicalDevice physical_device;
std::vector<std::string> extensions;
bool use_multiple_queues_per_family = false;
std::vector<float> graphics_queue_priorities;
std::vector<float> compute_queue_priorities;
std::vector<float> transfer_queue_priorities;
std::vector<float> sparse_queue_priorities;
} info;
};