2
0
Эх сурвалжийг харах

gpu: Vulkan feature/extension lists do not need to be stored in the renderer

Ethan Lee 1 сар өмнө
parent
commit
b2585ac236

+ 102 - 93
src/gpu/vulkan/SDL_gpu_vulkan.c

@@ -1079,6 +1079,24 @@ struct VulkanCommandPool
     Uint32 inactiveCommandBufferCount;
 };
 
+// Feature Checks
+
+typedef struct VulkanFeatures
+{
+    Uint32 desiredApiVersion;
+    VkPhysicalDeviceFeatures desiredVulkan10DeviceFeatures;
+    VkPhysicalDeviceVulkan11Features desiredVulkan11DeviceFeatures;
+    VkPhysicalDeviceVulkan12Features desiredVulkan12DeviceFeatures;
+    VkPhysicalDeviceVulkan13Features desiredVulkan13DeviceFeatures;
+
+    bool usesCustomVulkanOptions;
+
+    Uint32 additionalDeviceExtensionCount;
+    const char **additionalDeviceExtensionNames;
+    Uint32 additionalInstanceExtensionCount;
+    const char **additionalInstanceExtensionNames;
+} VulkanFeatures;
+
 // Context
 
 struct VulkanRenderer
@@ -1087,23 +1105,12 @@ struct VulkanRenderer
     VkPhysicalDevice physicalDevice;
     VkPhysicalDeviceProperties2KHR physicalDeviceProperties;
     VkPhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties;
-    VkPhysicalDeviceFeatures desiredVulkan10DeviceFeatures;
     VkDevice logicalDevice;
     Uint8 integratedMemoryNotification;
     Uint8 outOfDeviceLocalMemoryWarning;
     Uint8 outofBARMemoryWarning;
     Uint8 fillModeOnlyWarning;
 
-    bool usesCustomVulkanOptions;
-    Uint32 desiredApiVersion;
-    VkPhysicalDeviceVulkan11Features desiredVulkan11DeviceFeatures;
-    VkPhysicalDeviceVulkan12Features desiredVulkan12DeviceFeatures;
-    VkPhysicalDeviceVulkan13Features desiredVulkan13DeviceFeatures;
-    Uint32 additionalDeviceExtensionCount;
-    const char **additionalDeviceExtensionNames;
-    Uint32 additionalInstanceExtensionCount;
-    const char **additionalInstanceExtensionNames;
-
     bool debugMode;
     bool preferLowPower;
     bool requireHardwareAcceleration;
@@ -11128,23 +11135,22 @@ static Uint8 VULKAN_INTERNAL_CheckInstanceExtensions(
     return allExtensionsSupported;
 }
 
-static Uint8 CheckOptInDeviceExtensions(VulkanRenderer *renderer,
-                                        VkPhysicalDevice physicalDevice,
+static Uint8 CheckOptInDeviceExtensions(VulkanFeatures *features,
                                         Uint32 numExtensions,
                                         VkExtensionProperties *availableExtensions,
                                         const char **missingExtensionName) {
     Uint8 supportsAll = 1;
-    for (Uint32 extensionIdx = 0; extensionIdx < renderer->additionalDeviceExtensionCount; extensionIdx++) {
+    for (Uint32 extensionIdx = 0; extensionIdx < features->additionalDeviceExtensionCount; extensionIdx++) {
         bool found = false;
         for (Uint32 searchIdx = 0; searchIdx < numExtensions; searchIdx++) {
-            if (SDL_strcmp(renderer->additionalDeviceExtensionNames[extensionIdx], availableExtensions[searchIdx].extensionName) == 0) {
+            if (SDL_strcmp(features->additionalDeviceExtensionNames[extensionIdx], availableExtensions[searchIdx].extensionName) == 0) {
                 found = true;
                 break;
             }
         }
         if (!found) {
             supportsAll = 0;
-            *missingExtensionName = renderer->additionalDeviceExtensionNames[extensionIdx];
+            *missingExtensionName = features->additionalDeviceExtensionNames[extensionIdx];
             break;
         }
     }
@@ -11154,6 +11160,7 @@ static Uint8 CheckOptInDeviceExtensions(VulkanRenderer *renderer,
 
 static Uint8 VULKAN_INTERNAL_CheckDeviceExtensions(
     VulkanRenderer *renderer,
+    VulkanFeatures *features,
     VkPhysicalDevice physicalDevice,
     VulkanExtensions *physicalDeviceExtensions)
 {
@@ -11179,9 +11186,9 @@ static Uint8 VULKAN_INTERNAL_CheckDeviceExtensions(
         extensionCount,
         physicalDeviceExtensions);
 
-    if (renderer->usesCustomVulkanOptions) {
+    if (features->usesCustomVulkanOptions) {
         const char *missingExtensionName;
-        if (!CheckOptInDeviceExtensions(renderer, physicalDevice, extensionCount, availableExtensions, &missingExtensionName)) {
+        if (!CheckOptInDeviceExtensions(features, extensionCount, availableExtensions, &missingExtensionName)) {
             SDL_assert(missingExtensionName);
             if (renderer->debugMode) {
                 SDL_LogError(SDL_LOG_CATEGORY_GPU,
@@ -11416,14 +11423,14 @@ static bool VULKAN_INTERNAL_ValidateOptInVulkan13Features(VkPhysicalDeviceVulkan
 
 #undef CHECK_OPTIONAL_DEVICE_FEATURE
 
-static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *vk10Features)
+static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VulkanFeatures *features, VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *vk10Features)
 {
     bool supportsAllFeatures = true;
 
-    int minorVersion = VK_API_VERSION_MINOR(renderer->desiredApiVersion);
+    int minorVersion = VK_API_VERSION_MINOR(features->desiredApiVersion);
 
     if (minorVersion < 1) {
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
     } else if (minorVersion < 2) {
         // Query device features using the pre-1.2 structures
         VkPhysicalDevice16BitStorageFeatures storage = { 0 };
@@ -11472,8 +11479,8 @@ static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPh
         vk11Features.variablePointersStorageBuffer = varPointers.variablePointersStorageBuffer;
 
         // Check support
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&renderer->desiredVulkan11DeviceFeatures, &vk11Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&features->desiredVulkan11DeviceFeatures, &vk11Features);
     } else {
         VkPhysicalDeviceVulkan11Features vk11Features = { 0 };
         vk11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
@@ -11492,10 +11499,10 @@ static bool VULKAN_INTERNAL_ValidateOptInFeatures(VulkanRenderer *renderer, VkPh
 
         renderer->vkGetPhysicalDeviceFeatures2(physicalDevice, &supportedFeatureList);
 
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&renderer->desiredVulkan10DeviceFeatures, vk10Features);
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&renderer->desiredVulkan11DeviceFeatures, &vk11Features);
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan12Features(&renderer->desiredVulkan12DeviceFeatures, &vk12Features);
-        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan13Features(&renderer->desiredVulkan13DeviceFeatures, &vk13Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan10Features(&features->desiredVulkan10DeviceFeatures, vk10Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan11Features(&features->desiredVulkan11DeviceFeatures, &vk11Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan12Features(&features->desiredVulkan12DeviceFeatures, &vk12Features);
+        supportsAllFeatures &= VULKAN_INTERNAL_ValidateOptInVulkan13Features(&features->desiredVulkan13DeviceFeatures, &vk13Features);
     }
 
     return supportsAllFeatures;
@@ -11629,35 +11636,35 @@ static bool VULKAN_INTERNAL_TryAddDeviceFeatures_Vulkan_12_Or_Later(VkPhysicalDe
     return hasAdded;
 }
 
-static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, VulkanRenderer *renderer)
+static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, VulkanRenderer *renderer, VulkanFeatures *features)
 {
     if (SDL_HasProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER)) {
         SDL_GPUVulkanOptions *options = (SDL_GPUVulkanOptions *)SDL_GetPointerProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_OPTIONS_POINTER, NULL);
         if (options) {
-            renderer->usesCustomVulkanOptions = true;
-            renderer->desiredApiVersion = options->vulkan_api_version;
+            features->usesCustomVulkanOptions = true;
+            features->desiredApiVersion = options->vulkan_api_version;
 
-            SDL_memset(&renderer->desiredVulkan11DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan11Features));
-            SDL_memset(&renderer->desiredVulkan12DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan12Features));
-            SDL_memset(&renderer->desiredVulkan13DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan13Features));
-            renderer->desiredVulkan11DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
-            renderer->desiredVulkan12DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
-            renderer->desiredVulkan13DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
+            SDL_memset(&features->desiredVulkan11DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan11Features));
+            SDL_memset(&features->desiredVulkan12DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan12Features));
+            SDL_memset(&features->desiredVulkan13DeviceFeatures, 0, sizeof(VkPhysicalDeviceVulkan13Features));
+            features->desiredVulkan11DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+            features->desiredVulkan12DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+            features->desiredVulkan13DeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
 
             // Handle requested device features
-            VkPhysicalDeviceFeatures *vk10Features = &renderer->desiredVulkan10DeviceFeatures;
-            VkPhysicalDeviceVulkan11Features *vk11Features = &renderer->desiredVulkan11DeviceFeatures;
-            VkPhysicalDeviceVulkan12Features *vk12Features = &renderer->desiredVulkan12DeviceFeatures;
-            VkPhysicalDeviceVulkan13Features *vk13Features = &renderer->desiredVulkan13DeviceFeatures;
+            VkPhysicalDeviceFeatures *vk10Features = &features->desiredVulkan10DeviceFeatures;
+            VkPhysicalDeviceVulkan11Features *vk11Features = &features->desiredVulkan11DeviceFeatures;
+            VkPhysicalDeviceVulkan12Features *vk12Features = &features->desiredVulkan12DeviceFeatures;
+            VkPhysicalDeviceVulkan13Features *vk13Features = &features->desiredVulkan13DeviceFeatures;
 
             if (options->vulkan_10_physical_device_features) {
-                VkPhysicalDeviceFeatures *features = (VkPhysicalDeviceFeatures *)options->vulkan_10_physical_device_features;
+                VkPhysicalDeviceFeatures *deviceFeatures = (VkPhysicalDeviceFeatures *)options->vulkan_10_physical_device_features;
                 VULKAN_INTERNAL_AddDeviceFeatures(&vk10Features->robustBufferAccess,
                                                   &vk10Features->inheritedQueries,
-                                                  &features->robustBufferAccess);
+                                                  &deviceFeatures->robustBufferAccess);
             }
 
-            int minorVersion = VK_API_VERSION_MINOR(renderer->desiredApiVersion);
+            int minorVersion = VK_API_VERSION_MINOR(features->desiredApiVersion);
             bool supportsHigherLevelFeatures = minorVersion > 0;
             if (supportsHigherLevelFeatures && options->feature_list) {
                 if (minorVersion < 2) {
@@ -11675,17 +11682,17 @@ static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, Vulkan
                                                                                 vk11Features,
                                                                                 vk12Features,
                                                                                 vk13Features,
-                                                                                renderer->desiredApiVersion,
+                                                                                features->desiredApiVersion,
                                                                                 nextStructure);
                         nextStructure = nextStructure->pNext;
                     }
                 }
             }
 
-            renderer->additionalDeviceExtensionCount = options->device_extension_count;
-            renderer->additionalDeviceExtensionNames = options->device_extension_names;
-            renderer->additionalInstanceExtensionCount = options->instance_extension_count;
-            renderer->additionalInstanceExtensionNames = options->instance_extension_names;
+            features->additionalDeviceExtensionCount = options->device_extension_count;
+            features->additionalDeviceExtensionNames = options->device_extension_names;
+            features->additionalInstanceExtensionCount = options->instance_extension_count;
+            features->additionalInstanceExtensionNames = options->instance_extension_names;
         } else if (renderer->debugMode) {
             SDL_LogWarn(SDL_LOG_CATEGORY_GPU,
                         "VULKAN_INTERNAL_AddOptInVulkanOptions: Additional options property was set, but value was null. This may be a bug.");
@@ -11693,7 +11700,7 @@ static void VULKAN_INTERNAL_AddOptInVulkanOptions(SDL_PropertiesID props, Vulkan
     }
 }
 
-static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
+static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer, VulkanFeatures *features)
 {
     VkResult vulkanResult;
     VkApplicationInfo appInfo;
@@ -11710,8 +11717,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
     appInfo.applicationVersion = 0;
     appInfo.pEngineName = "SDLGPU";
     appInfo.engineVersion = SDL_VERSION;
-    appInfo.apiVersion = renderer->usesCustomVulkanOptions
-                             ? renderer->desiredApiVersion
+    appInfo.apiVersion = features->usesCustomVulkanOptions
+                             ? features->desiredApiVersion
                              : VK_MAKE_VERSION(1, 0, 0);
 
     createFlags = 0;
@@ -11726,8 +11733,8 @@ static Uint8 VULKAN_INTERNAL_CreateInstance(VulkanRenderer *renderer)
         return 0;
     }
 
-    Uint32 extraInstanceExtensionCount = renderer->additionalInstanceExtensionCount;
-    const char** extraInstanceExtensionNames = renderer->additionalInstanceExtensionNames;
+    Uint32 extraInstanceExtensionCount = features->additionalInstanceExtensionCount;
+    const char** extraInstanceExtensionNames = features->additionalInstanceExtensionNames;
 
     /* Extra space for the following extensions:
      * VK_KHR_get_physical_device_properties2
@@ -11940,6 +11947,7 @@ static bool VULKAN_INTERNAL_GetDeviceRank(
 
 static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
     VulkanRenderer *renderer,
+    VulkanFeatures *features,
     VkPhysicalDevice physicalDevice,
     VulkanExtensions *physicalDeviceExtensions,
     Uint32 *queueFamilyIndex)
@@ -11954,19 +11962,19 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
         physicalDevice,
         &deviceFeatures);
 
-    if ((!deviceFeatures.independentBlend && renderer->desiredVulkan10DeviceFeatures.independentBlend) ||
-        (!deviceFeatures.imageCubeArray && renderer->desiredVulkan10DeviceFeatures.imageCubeArray) ||
-        (!deviceFeatures.depthClamp && renderer->desiredVulkan10DeviceFeatures.depthClamp) ||
-        (!deviceFeatures.shaderClipDistance && renderer->desiredVulkan10DeviceFeatures.shaderClipDistance) ||
-        (!deviceFeatures.drawIndirectFirstInstance && renderer->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance) ||
-        (!deviceFeatures.sampleRateShading && renderer->desiredVulkan10DeviceFeatures.sampleRateShading) ||
-        (!deviceFeatures.samplerAnisotropy && renderer->desiredVulkan10DeviceFeatures.samplerAnisotropy)) {
+    if ((!deviceFeatures.independentBlend && features->desiredVulkan10DeviceFeatures.independentBlend) ||
+        (!deviceFeatures.imageCubeArray && features->desiredVulkan10DeviceFeatures.imageCubeArray) ||
+        (!deviceFeatures.depthClamp && features->desiredVulkan10DeviceFeatures.depthClamp) ||
+        (!deviceFeatures.shaderClipDistance && features->desiredVulkan10DeviceFeatures.shaderClipDistance) ||
+        (!deviceFeatures.drawIndirectFirstInstance && features->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance) ||
+        (!deviceFeatures.sampleRateShading && features->desiredVulkan10DeviceFeatures.sampleRateShading) ||
+        (!deviceFeatures.samplerAnisotropy && features->desiredVulkan10DeviceFeatures.samplerAnisotropy)) {
         return 0;
     }
 
     // Check opt-in device features
-    if (renderer->usesCustomVulkanOptions) {
-        bool supportsAllFeatures = VULKAN_INTERNAL_ValidateOptInFeatures(renderer, physicalDevice, &deviceFeatures);
+    if (features->usesCustomVulkanOptions) {
+        bool supportsAllFeatures = VULKAN_INTERNAL_ValidateOptInFeatures(renderer, features, physicalDevice, &deviceFeatures);
         if (!supportsAllFeatures) {
             return 0;
         }
@@ -11974,6 +11982,7 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
 
     if (!VULKAN_INTERNAL_CheckDeviceExtensions(
             renderer,
+            features,
             physicalDevice,
             physicalDeviceExtensions)) {
         return 0;
@@ -12057,7 +12066,7 @@ static Uint8 VULKAN_INTERNAL_IsDeviceSuitable(
     return 1;
 }
 
-static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
+static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer, VulkanFeatures *features)
 {
     VkResult vulkanResult;
     VkPhysicalDevice *physicalDevices;
@@ -12116,6 +12125,7 @@ static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
 
         if (!VULKAN_INTERNAL_IsDeviceSuitable(
                 renderer,
+                features,
                 physicalDevices[i],
                 &physicalDeviceExtensions[i],
                 &queueFamilyIndex)) {
@@ -12180,7 +12190,8 @@ static Uint8 VULKAN_INTERNAL_DeterminePhysicalDevice(VulkanRenderer *renderer)
 }
 
 static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
-    VulkanRenderer *renderer)
+    VulkanRenderer *renderer,
+    VulkanFeatures *features)
 {
     VkResult vulkanResult;
     VkDeviceCreateInfo deviceCreateInfo;
@@ -12208,12 +12219,12 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
     // specifying used device features
 
     if (haveDeviceFeatures.fillModeNonSolid) {
-        renderer->desiredVulkan10DeviceFeatures.fillModeNonSolid = VK_TRUE;
+        features->desiredVulkan10DeviceFeatures.fillModeNonSolid = VK_TRUE;
         renderer->supportsFillModeNonSolid = true;
     }
 
     if (haveDeviceFeatures.multiDrawIndirect) {
-        renderer->desiredVulkan10DeviceFeatures.multiDrawIndirect = VK_TRUE;
+        features->desiredVulkan10DeviceFeatures.multiDrawIndirect = VK_TRUE;
         renderer->supportsMultiDrawIndirect = true;
     }
 
@@ -12256,17 +12267,17 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice(
     deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions;
 
     VkPhysicalDeviceFeatures2 featureList;
-    if (renderer->usesCustomVulkanOptions) {
+    if (features->usesCustomVulkanOptions) {
         featureList.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
-        featureList.features = renderer->desiredVulkan10DeviceFeatures;
-        featureList.pNext = &renderer->desiredVulkan11DeviceFeatures;
-        renderer->desiredVulkan11DeviceFeatures.pNext = &renderer->desiredVulkan12DeviceFeatures;
-        renderer->desiredVulkan12DeviceFeatures.pNext = &renderer->desiredVulkan13DeviceFeatures;
-        renderer->desiredVulkan13DeviceFeatures.pNext = (void *)deviceCreateInfo.pNext;
+        featureList.features = features->desiredVulkan10DeviceFeatures;
+        featureList.pNext = &features->desiredVulkan11DeviceFeatures;
+        features->desiredVulkan11DeviceFeatures.pNext = &features->desiredVulkan12DeviceFeatures;
+        features->desiredVulkan12DeviceFeatures.pNext = &features->desiredVulkan13DeviceFeatures;
+        features->desiredVulkan13DeviceFeatures.pNext = (void *)deviceCreateInfo.pNext;
         deviceCreateInfo.pEnabledFeatures = NULL;
         deviceCreateInfo.pNext = &featureList;
     } else {
-        deviceCreateInfo.pEnabledFeatures = &renderer->desiredVulkan10DeviceFeatures;
+        deviceCreateInfo.pEnabledFeatures = &features->desiredVulkan10DeviceFeatures;
     }
 
     vulkanResult = renderer->vkCreateDevice(
@@ -12333,27 +12344,30 @@ static void VULKAN_INTERNAL_LoadEntryPoints(void)
 
 static bool VULKAN_INTERNAL_PrepareVulkan(
     VulkanRenderer *renderer,
+    VulkanFeatures *features,
     SDL_PropertiesID props)
 {
     VULKAN_INTERNAL_LoadEntryPoints();
 
+    SDL_zerop(features);
+
     // Opt out device features (higher compatibility in exchange for reduced functionality)
-    renderer->desiredVulkan10DeviceFeatures.samplerAnisotropy = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
-    renderer->desiredVulkan10DeviceFeatures.depthClamp = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
-    renderer->desiredVulkan10DeviceFeatures.shaderClipDistance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
-    renderer->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
+    features->desiredVulkan10DeviceFeatures.samplerAnisotropy = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
+    features->desiredVulkan10DeviceFeatures.depthClamp = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
+    features->desiredVulkan10DeviceFeatures.shaderClipDistance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
+    features->desiredVulkan10DeviceFeatures.drawIndirectFirstInstance = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, true) ? VK_TRUE : VK_FALSE;
 
     // These features have near universal support so they are always enabled
-    renderer->desiredVulkan10DeviceFeatures.independentBlend = VK_TRUE;
-    renderer->desiredVulkan10DeviceFeatures.sampleRateShading = VK_TRUE;
-    renderer->desiredVulkan10DeviceFeatures.imageCubeArray = VK_TRUE;
+    features->desiredVulkan10DeviceFeatures.independentBlend = VK_TRUE;
+    features->desiredVulkan10DeviceFeatures.sampleRateShading = VK_TRUE;
+    features->desiredVulkan10DeviceFeatures.imageCubeArray = VK_TRUE;
 
     // Handle opt-in device features
-    VULKAN_INTERNAL_AddOptInVulkanOptions(props, renderer);
+    VULKAN_INTERNAL_AddOptInVulkanOptions(props, renderer, features);
 
     renderer->requireHardwareAcceleration = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_VULKAN_REQUIRE_HARDWARE_ACCELERATION_BOOLEAN, false);
 
-    if (!VULKAN_INTERNAL_CreateInstance(renderer)) {
+    if (!VULKAN_INTERNAL_CreateInstance(renderer, features)) {
         SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Vulkan: Could not create Vulkan instance");
         return false;
     }
@@ -12362,7 +12376,7 @@ static bool VULKAN_INTERNAL_PrepareVulkan(
     renderer->func = (PFN_##func)vkGetInstanceProcAddr(renderer->instance, #func);
 #include "SDL_gpu_vulkan_vkfuncs.h"
 
-    if (!VULKAN_INTERNAL_DeterminePhysicalDevice(renderer)) {
+    if (!VULKAN_INTERNAL_DeterminePhysicalDevice(renderer, features)) {
         SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Vulkan: Failed to determine a suitable physical device");
         return false;
     }
@@ -12373,6 +12387,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
 {
     // Set up dummy VulkanRenderer
     VulkanRenderer *renderer;
+    VulkanFeatures features;
     bool result = false;
 
     if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false)) {
@@ -12394,7 +12409,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
 
         renderer->preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
 
-        result = VULKAN_INTERNAL_PrepareVulkan(renderer, props);
+        result = VULKAN_INTERNAL_PrepareVulkan(renderer, &features, props);
         if (result) {
             renderer->vkDestroyInstance(renderer->instance, NULL);
         }
@@ -12409,6 +12424,7 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props)
 static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
 {
     VulkanRenderer *renderer;
+    VulkanFeatures features;
 
     SDL_GPUDevice *result;
     Uint32 i;
@@ -12433,19 +12449,13 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
     renderer->preferLowPower = preferLowPower;
     renderer->allowedFramesInFlight = 2;
 
-    if (!VULKAN_INTERNAL_PrepareVulkan(renderer, props)) {
+    if (!VULKAN_INTERNAL_PrepareVulkan(renderer, &features, props)) {
         SET_STRING_ERROR("Failed to initialize Vulkan!");
         SDL_free(renderer);
         SDL_Vulkan_UnloadLibrary();
         return NULL;
     }
 
-    // Make sure we don't hold onto potentially unsafe pointers after initialization
-    renderer->additionalDeviceExtensionCount = 0;
-    renderer->additionalInstanceExtensionCount = 0;
-    renderer->additionalDeviceExtensionNames = NULL;
-    renderer->additionalInstanceExtensionNames = NULL;
-
     renderer->props = SDL_CreateProperties();
     if (verboseLogs) {
         SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan");
@@ -12546,8 +12556,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
         }
     }
 
-    if (!VULKAN_INTERNAL_CreateLogicalDevice(
-            renderer)) {
+    if (!VULKAN_INTERNAL_CreateLogicalDevice(renderer, &features)) {
         SET_STRING_ERROR("Failed to create logical device!");
         SDL_free(renderer);
         SDL_Vulkan_UnloadLibrary();