From e48e8a48adccb722ad52ea3b4dc0af5a6edb3fbf Mon Sep 17 00:00:00 2001 From: Madeline Whitmore Date: Mon, 26 Jan 2026 05:18:57 +1300 Subject: [PATCH] SDL GPU: Fix features not being enabled with Vulkan 1.1 (#14885) Use pre-Vulkan 1.2 structs to request features from a Vulkan 1.1 instance. (cherry picked from commit 97b177c92faedcfc67c0bae54d2411d9550cf68b) --- src/gpu/vulkan/SDL_gpu_vulkan.c | 53 ++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index e87b5eec9b..be3598f991 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -12278,13 +12278,58 @@ static Uint8 VULKAN_INTERNAL_CreateLogicalDevice( VkPhysicalDeviceFeatures2 featureList; int minor = VK_VERSION_MINOR(features->desiredApiVersion); + struct { + VkPhysicalDevice16BitStorageFeatures storage; + VkPhysicalDeviceMultiviewFeatures multiview; + VkPhysicalDeviceProtectedMemoryFeatures protectedMem; + VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr; + VkPhysicalDeviceShaderDrawParametersFeatures drawParams; + VkPhysicalDeviceVariablePointersFeatures varPointers; + } legacyFeatures; + if (features->usesCustomVulkanOptions && minor > 0) { featureList.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; featureList.features = features->desiredVulkan10DeviceFeatures; - featureList.pNext = minor > 1 ? &features->desiredVulkan11DeviceFeatures : NULL; - features->desiredVulkan11DeviceFeatures.pNext = &features->desiredVulkan12DeviceFeatures; - features->desiredVulkan12DeviceFeatures.pNext = minor > 2 ? &features->desiredVulkan13DeviceFeatures : NULL; - features->desiredVulkan13DeviceFeatures.pNext = NULL; + if (minor > 1) { + featureList.pNext = &features->desiredVulkan11DeviceFeatures; + features->desiredVulkan11DeviceFeatures.pNext = &features->desiredVulkan12DeviceFeatures; + features->desiredVulkan12DeviceFeatures.pNext = minor > 2 ? &features->desiredVulkan13DeviceFeatures : NULL; + features->desiredVulkan13DeviceFeatures.pNext = NULL; + } else { + // Break VkPhysicalDeviceVulkan11Features into pre 1.2 structures for Vulkan 1.1 Support + SDL_zero(legacyFeatures); + + legacyFeatures.storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES; + legacyFeatures.storage.storageBuffer16BitAccess = features->desiredVulkan11DeviceFeatures.storageBuffer16BitAccess; + legacyFeatures.storage.storageInputOutput16 = features->desiredVulkan11DeviceFeatures.storageInputOutput16; + legacyFeatures.storage.storagePushConstant16 = features->desiredVulkan11DeviceFeatures.storagePushConstant16; + legacyFeatures.storage.uniformAndStorageBuffer16BitAccess = features->desiredVulkan11DeviceFeatures.uniformAndStorageBuffer16BitAccess; + + legacyFeatures.multiview.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES; + legacyFeatures.multiview.multiview = features->desiredVulkan11DeviceFeatures.multiview; + legacyFeatures.multiview.multiviewGeometryShader = features->desiredVulkan11DeviceFeatures.multiviewGeometryShader; + legacyFeatures.multiview.multiviewTessellationShader = features->desiredVulkan11DeviceFeatures.multiviewTessellationShader; + + legacyFeatures.protectedMem.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES; + legacyFeatures.protectedMem.protectedMemory = features->desiredVulkan11DeviceFeatures.protectedMemory; + + legacyFeatures.ycbcr.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES; + legacyFeatures.ycbcr.samplerYcbcrConversion = features->desiredVulkan11DeviceFeatures.samplerYcbcrConversion; + + legacyFeatures.drawParams.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; + legacyFeatures.drawParams.shaderDrawParameters = features->desiredVulkan11DeviceFeatures.shaderDrawParameters; + + legacyFeatures.varPointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES; + legacyFeatures.varPointers.variablePointers = features->desiredVulkan11DeviceFeatures.variablePointers; + legacyFeatures.varPointers.variablePointersStorageBuffer = features->desiredVulkan11DeviceFeatures.variablePointersStorageBuffer; + + featureList.pNext = &legacyFeatures.storage; + legacyFeatures.storage.pNext = &legacyFeatures.multiview; + legacyFeatures.multiview.pNext = &legacyFeatures.protectedMem; + legacyFeatures.protectedMem.pNext = &legacyFeatures.ycbcr; + legacyFeatures.ycbcr.pNext = &legacyFeatures.drawParams; + legacyFeatures.drawParams.pNext = &legacyFeatures.varPointers; + } deviceCreateInfo.pEnabledFeatures = NULL; deviceCreateInfo.pNext = &featureList; } else {