Переглянути джерело

Pick dedicated GPU with highest VRAM

suleyth 1 місяць тому
батько
коміт
c5b79e5f1b
1 змінених файлів з 21 додано та 2 видалено
  1. 21 2
      src/gpu/vulkan/SDL_gpu_vulkan.c

+ 21 - 2
src/gpu/vulkan/SDL_gpu_vulkan.c

@@ -11252,13 +11252,14 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
     VkPhysicalDevice physicalDevice,
     VulkanExtensions *physicalDeviceExtensions,
     Uint32 *queueFamilyIndex,
-    Uint8 *deviceRank)
+    Uint16 *deviceRank)
 {
     Uint32 queueFamilyCount, queueFamilyRank, queueFamilyBest;
     VkQueueFamilyProperties *queueProps;
     bool supportsPresent;
     VkPhysicalDeviceProperties deviceProperties;
     VkPhysicalDeviceFeatures deviceFeatures;
+    VkPhysicalDeviceMemoryProperties deviceMemory;
     Uint32 i;
 
     const Uint8 *devicePriority = renderer->preferLowPower ? DEVICE_PRIORITY_LOWPOWER : DEVICE_PRIORITY_HIGHPERFORMANCE;
@@ -11285,6 +11286,24 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
         return 0;
     }
 
+    /* If we prefer high performance, sum up all device local memory (rounded to megabytes)
+     * to deviceRank. In the niche case of someone having multiple dedicated GPUs in the same
+     * system, this theoretically picks the most powerful one (or at least the one with the
+     * most memory!)
+     */
+
+    renderer->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &deviceMemory);
+    Uint64 videoMemory = 0;
+    for (i = 0; i < deviceMemory.memoryHeapCount; i++) {
+        VkMemoryHeap heap = deviceMemory.memoryHeaps[i];
+        if (heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
+            videoMemory += heap.size;
+        }
+    }
+    // Round it to megabytes (as per the vulkan spec videoMemory is in bytes)
+    Uint64 videoMemoryRounded = videoMemory / 1024 / 1024;
+    *deviceRank += videoMemoryRounded;
+
     renderer->vkGetPhysicalDeviceFeatures(
         physicalDevice,
         &deviceFeatures);
@@ -11392,7 +11411,7 @@ static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
     Uint32 i, physicalDeviceCount;
     Sint32 suitableIndex;
     Uint32 queueFamilyIndex, suitableQueueFamilyIndex;
-    Uint8 deviceRank, highestRank;
+    Uint16 deviceRank, highestRank;
 
     vulkanResult = renderer->vkEnumeratePhysicalDevices(
         renderer->instance,