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; VkPhysicalDeviceProperties device_properties;
vkGetPhysicalDeviceProperties (phys_device, &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) || 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) || 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)) { device_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)) {
if (criteria.allow_fallback) if (criteria.allow_fallback)
suitable = Suitable::partial; suitable = Suitable::partial;
@ -598,8 +598,14 @@ detail::Expected<PhysicalDevice, VkResult> PhysicalDeviceSelector::select () {
if (!physical_devices.has_value ()) { if (!physical_devices.has_value ()) {
return detail::Error{ physical_devices.error ().error_code, "Failed to find physical devices" }; 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; PhysicalDevice physical_device;
if (criteria.use_first_gpu_unconditionally) {
physical_device.phys_device = physical_devices.value ().at (0);
} else {
for (const auto& device : physical_devices.value ()) { for (const auto& device : physical_devices.value ()) {
auto suitable = is_device_suitable (device); auto suitable = is_device_suitable (device);
if (suitable == Suitable::yes) { if (suitable == Suitable::yes) {
@ -609,6 +615,7 @@ detail::Expected<PhysicalDevice, VkResult> PhysicalDeviceSelector::select () {
physical_device.phys_device = device; physical_device.phys_device = device;
} }
} }
}
if (physical_device.phys_device == VK_NULL_HANDLE) { if (physical_device.phys_device == VK_NULL_HANDLE) {
return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "Failed to find a suitable GPU!" }; return detail::Error{ VK_ERROR_INITIALIZATION_FAILED, "Failed to find a suitable GPU!" };
@ -638,19 +645,11 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_surface (VkSurfaceKHR surfac
info.headless = false; info.headless = false;
return *this; return *this;
} }
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_discrete () { PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_gpu_device_type (PreferredDeviceType type) {
criteria.preferred_type = PreferredDevice::discrete; criteria.preferred_type = type;
return *this; return *this;
} }
PhysicalDeviceSelector& PhysicalDeviceSelector::prefer_integrated () { PhysicalDeviceSelector& PhysicalDeviceSelector::allow_fallback_gpu (bool fallback) {
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) {
criteria.allow_fallback = fallback; criteria.allow_fallback = fallback;
return *this; return *this;
} }
@ -678,10 +677,20 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::add_required_extension (std::str
criteria.required_extensions.push_back (extension); criteria.required_extensions.push_back (extension);
return *this; 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) { PhysicalDeviceSelector& PhysicalDeviceSelector::add_desired_extension (std::string extension) {
criteria.desired_extensions.push_back (extension); criteria.desired_extensions.push_back (extension);
return *this; 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) { PhysicalDeviceSelector& PhysicalDeviceSelector::set_minimum_version (uint32_t major, uint32_t minor) {
criteria.required_version = VK_MAKE_VERSION (major, minor, 0); criteria.required_version = VK_MAKE_VERSION (major, minor, 0);
return *this; return *this;
@ -694,6 +703,14 @@ PhysicalDeviceSelector& PhysicalDeviceSelector::set_required_features (VkPhysica
criteria.required_features = features; criteria.required_features = features;
return *this; 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 ---- // // ---- Device ---- //
@ -711,16 +728,33 @@ DeviceBuilder::DeviceBuilder (PhysicalDevice phys_device) {
detail::Expected<Device, VkResult> DeviceBuilder::build () { detail::Expected<Device, VkResult> DeviceBuilder::build () {
auto& queue_properties = info.physical_device.queue_family_properties; auto& queue_properties = info.physical_device.queue_family_properties;
std::vector<QueueFamily> families; 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.graphics,
families.push_back ({ queue_properties.compute, std::vector<float> (queue_properties.count_compute) }); 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 && if (queue_properties.transfer != -1 && queue_properties.transfer != queue_properties.graphics &&
queue_properties.transfer != queue_properties.compute) 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 && if (queue_properties.sparse != -1 && queue_properties.sparse != queue_properties.graphics &&
queue_properties.sparse != queue_properties.compute && queue_properties.sparse != queue_properties.compute &&
queue_properties.sparse != queue_properties.transfer) 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; std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
for (auto& queue : families) { 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)); info.pNext_chain.push_back (reinterpret_cast<VkBaseOutStructure*> (structure));
return *this; 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 ---- // // ---- Queue ---- //

View File

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