mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Improve Vulkan device selection mechanism to prefer discrete GPUs
This commit is contained in:
parent
c855ab66d5
commit
c6c90d4cbc
3 changed files with 61 additions and 12 deletions
|
@ -120,6 +120,11 @@ VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32
|
|||
}
|
||||
|
||||
VulkanLoadInstanceFunctions(instance_);
|
||||
if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) {
|
||||
WLOG("CheckLayers for instance failed");
|
||||
// init_error_ = "Failed to validate instance layers";
|
||||
// return;
|
||||
}
|
||||
|
||||
uint32_t gpu_count = 1;
|
||||
res = vkEnumeratePhysicalDevices(instance_, &gpu_count, nullptr);
|
||||
|
@ -141,11 +146,6 @@ VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32
|
|||
return res;
|
||||
}
|
||||
|
||||
if (!CheckLayers(instance_layer_properties_, instance_layer_names_)) {
|
||||
WLOG("CheckLayers failed");
|
||||
// init_error_ = "Failed to validate instance layers";
|
||||
// return;
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -333,14 +333,47 @@ bool VulkanContext::CheckLayers(const std::vector<LayerProperties> &layer_props,
|
|||
return true;
|
||||
}
|
||||
|
||||
int VulkanContext::GetBestPhysicalDevice() {
|
||||
// Rules: Prefer discrete over embedded.
|
||||
// Prefer nVidia over Intel.
|
||||
|
||||
int maxScore = -1;
|
||||
int best = -1;
|
||||
|
||||
for (size_t i = 0; i < physical_devices_.size(); i++) {
|
||||
int score = 0;
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(physical_devices_[i], &props);
|
||||
switch (props.deviceType) {
|
||||
case VK_PHYSICAL_DEVICE_TYPE_CPU:
|
||||
score += 1;
|
||||
break;
|
||||
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
|
||||
score += 20;
|
||||
break;
|
||||
case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
|
||||
score += 10;
|
||||
break;
|
||||
}
|
||||
if (props.vendorID == VULKAN_VENDOR_AMD) {
|
||||
score += 5;
|
||||
} else if (props.vendorID == VULKAN_VENDOR_NVIDIA) {
|
||||
score += 5;
|
||||
}
|
||||
if (score > maxScore) {
|
||||
best = i;
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
void VulkanContext::ChooseDevice(int physical_device) {
|
||||
physical_device_ = physical_device;
|
||||
|
||||
GetDeviceLayerProperties();
|
||||
if (!CheckLayers(device_layer_properties_, device_layer_names_)) {
|
||||
WLOG("CheckLayers failed (2)");
|
||||
// init_error_ = "Failed to validate device layers";
|
||||
// return;
|
||||
WLOG("CheckLayers for device %d failed", physical_device);
|
||||
}
|
||||
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_devices_[physical_device_], &queue_count, nullptr);
|
||||
|
@ -913,4 +946,4 @@ const char *VulkanResultToString(VkResult res) {
|
|||
default:
|
||||
return "VK_ERROR_...(unknown)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,15 @@ enum {
|
|||
VULKAN_FLAG_PRESENT_FIFO_RELAXED = 8,
|
||||
};
|
||||
|
||||
enum {
|
||||
VULKAN_VENDOR_NVIDIA = 0x000010de,
|
||||
VULKAN_VENDOR_INTEL = 0x00008086, // Haha!
|
||||
VULKAN_VENDOR_AMD = 0x00001002,
|
||||
VULKAN_VENDOR_ARM = 0x000013B5, // Mali
|
||||
VULKAN_VENDOR_QUALCOMM = 0x00005143,
|
||||
VULKAN_VENDOR_IMGTEC = 0x00001010, // PowerVR
|
||||
};
|
||||
|
||||
struct VulkanPhysicalDeviceInfo {
|
||||
VkFormat preferredDepthStencilFormat;
|
||||
};
|
||||
|
@ -203,8 +212,7 @@ public:
|
|||
|
||||
VkResult CreateInstance(const char *app_name, int app_ver, uint32_t flags);
|
||||
|
||||
// TODO: Actually do some checks?
|
||||
int GetBestPhysicalDevice() const { return 0; }
|
||||
int GetBestPhysicalDevice();
|
||||
void ChooseDevice(int physical_device);
|
||||
bool EnableDeviceExtension(const char *extension);
|
||||
VkResult CreateDevice();
|
||||
|
|
|
@ -290,7 +290,15 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
|||
return false;
|
||||
}
|
||||
|
||||
g_Vulkan->ChooseDevice(g_Vulkan->GetBestPhysicalDevice());
|
||||
int physicalDevice = g_Vulkan->GetBestPhysicalDevice();
|
||||
if (physicalDevice < 0) {
|
||||
ELOG("No usable Vulkan device found.");
|
||||
delete g_Vulkan;
|
||||
g_Vulkan = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
g_Vulkan->ChooseDevice(physicalDevice);
|
||||
// Here we can enable device extensions if we like.
|
||||
|
||||
ILOG("Creating vulkan device");
|
||||
|
|
Loading…
Add table
Reference in a new issue