From b2585ac2369c563ce91962b6ac2382bb40e36340 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Tue, 11 Nov 2025 21:24:45 -0500 Subject: [PATCH] gpu: Vulkan feature/extension lists do not need to be stored in the renderer --- src/gpu/vulkan/SDL_gpu_vulkan.c | 195 +++++++++++++++++--------------- 1 file changed, 102 insertions(+), 93 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 0b7e0abae3..c0e64ebf24 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/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();