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

vulkan: Only enable KHR_portability_enumeration when available

Ethan Lee 1 тиждень тому
батько
коміт
910d31e56a
2 змінених файлів з 71 додано та 11 видалено
  1. 15 7
      src/gpu/vulkan/SDL_gpu_vulkan.c
  2. 56 4
      test/testvulkan.c

+ 15 - 7
src/gpu/vulkan/SDL_gpu_vulkan.c

@@ -1123,6 +1123,7 @@ struct VulkanRenderer
     bool supportsDebugUtils;
     bool supportsColorspace;
     bool supportsPhysicalDeviceProperties2;
+    bool supportsPortabilityEnumeration;
     bool supportsFillModeNonSolid;
     bool supportsMultiDrawIndirect;
 
@@ -11104,6 +11105,7 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
     bool *supportsDebugUtils,
     bool *supportsColorspace,
     bool *supportsPhysicalDeviceProperties2,
+    bool *supportsPortabilityEnumeration,
     int *firstUnsupportedExtensionIndex)
 {
     Uint32 extensionCount, i;
@@ -11150,6 +11152,12 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
         availableExtensions,
         extensionCount);
 
+    // Only needed for MoltenVK!
+    *supportsPortabilityEnumeration = SupportsInstanceExtension(
+        VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
+        availableExtensions,
+        extensionCount);
+
     SDL_free(availableExtensions);
     return allExtensionsSupported;
 }
@@ -11775,13 +11783,6 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
         nextInstanceExtensionNamePtr += extraInstanceExtensionCount;
     }
 
-
-#ifdef SDL_PLATFORM_APPLE
-    *nextInstanceExtensionNamePtr++ = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
-    instanceExtensionCount++;
-    createFlags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
-#endif
-
     int firstUnsupportedExtensionIndex = 0;
     if (!VULKAN_INTERNAL_CheckInstanceExtensions(
             instanceExtensionNames,
@@ -11789,6 +11790,7 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
             &renderer->supportsDebugUtils,
             &renderer->supportsColorspace,
             &renderer->supportsPhysicalDeviceProperties2,
+            &renderer->supportsPortabilityEnumeration,
             &firstUnsupportedExtensionIndex)) {
         if (renderer->debugMode) {
             SDL_LogError(SDL_LOG_CATEGORY_GPU,
@@ -11824,6 +11826,12 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeat
         instanceExtensionCount++;
     }
 
+    if (renderer->supportsPortabilityEnumeration) {
+        *nextInstanceExtensionNamePtr++ = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
+        instanceExtensionCount++;
+        createFlags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
+    }
+
     createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
     createInfo.pNext = NULL;
     createInfo.flags = createFlags;

+ 56 - 4
test/testvulkan.c

@@ -218,22 +218,74 @@ static void loadGlobalFunctions(void)
 #undef VULKAN_INSTANCE_FUNCTION
 }
 
+static bool checkVulkanPortability(void)
+{
+    Uint32 extensionCount, i;
+    VkExtensionProperties *availableExtensions;
+    bool supported = false;
+
+    vkEnumerateInstanceExtensionProperties(
+        NULL,
+        &extensionCount,
+        NULL);
+    availableExtensions = SDL_malloc(
+        extensionCount * sizeof(VkExtensionProperties));
+    vkEnumerateInstanceExtensionProperties(
+        NULL,
+        &extensionCount,
+        availableExtensions);
+
+    for (i = 0; i < extensionCount; i += 1) {
+        if (SDL_strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, availableExtensions[i].extensionName) == 0) {
+            supported = true;
+            break;
+        }
+    }
+
+    SDL_free(availableExtensions);
+    return supported;
+}
+
 static void createInstance(void)
 {
     VkApplicationInfo appInfo = { 0 };
     VkInstanceCreateInfo instanceCreateInfo = { 0 };
+    bool supportsPortabilityEnumeration;
+    const char **instanceExtensions;
     VkResult result;
 
     appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
     appInfo.apiVersion = VK_API_VERSION_1_0;
     instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
     instanceCreateInfo.pApplicationInfo = &appInfo;
-#ifdef __APPLE__
-    instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
-#endif
 
-    instanceCreateInfo.ppEnabledExtensionNames = SDL_Vulkan_GetInstanceExtensions(&instanceCreateInfo.enabledExtensionCount);
+    supportsPortabilityEnumeration = checkVulkanPortability();
+    if (supportsPortabilityEnumeration) {
+        // Allocate our own extension array so that we can add the KHR_portability extensions for MoltenVK
+        Uint32 count_instance_extensions;
+        const char * const *instance_extensions = SDL_Vulkan_GetInstanceExtensions(&count_instance_extensions);
+
+        int count_extensions = count_instance_extensions + 1;
+        instanceExtensions = SDL_malloc(count_extensions * sizeof(const char *));
+        instanceExtensions[0] = VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
+        SDL_memcpy(&instanceExtensions[1], instance_extensions, count_instance_extensions * sizeof(const char*));
+
+        instanceCreateInfo.enabledExtensionCount = count_extensions;
+        instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions;
+        instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
+    } else {
+        // No need to allocate anything, just use SDL's array directly
+        instanceExtensions = NULL;
+        instanceCreateInfo.ppEnabledExtensionNames =
+            SDL_Vulkan_GetInstanceExtensions(&instanceCreateInfo.enabledExtensionCount);
+    }
+
     result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext->instance);
+
+    if (instanceExtensions != NULL) {
+        SDL_free(instanceExtensions);
+    }
+
     if (result != VK_SUCCESS) {
         vulkanContext->instance = VK_NULL_HANDLE;
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,