Merge pull request #3721 from ReinUsesLisp/sort-devices

vulkan/wrapper: Sort physical devices
master
bunnei 2020-04-25 03:27:40 +07:00 committed by GitHub
commit c5bf693882
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 1 deletions

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm>
#include <exception> #include <exception>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -16,6 +17,23 @@ namespace Vulkan::vk {
namespace { namespace {
void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) {
// This will call Vulkan more than needed, but these calls are cheap.
const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties();
const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties();
// Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest.
const bool preferred =
(lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
(lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) ||
(lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) ||
(lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086);
return !preferred;
});
}
template <typename T> template <typename T>
bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name, bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name,
VkInstance instance = nullptr) noexcept { VkInstance instance = nullptr) noexcept {
@ -389,7 +407,8 @@ std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices(
if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) { if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) {
return std::nullopt; return std::nullopt;
} }
return physical_devices; SortPhysicalDevices(physical_devices, *dld);
return std::make_optional(std::move(physical_devices));
} }
DebugCallback Instance::TryCreateDebugCallback( DebugCallback Instance::TryCreateDebugCallback(