From 510126ee6375d49a0d620848dba295e04bb04ba5 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 19 May 2025 08:56:29 -0400 Subject: [PATCH] gpu: Check shader format support in PrepareDriver --- src/gpu/SDL_gpu.c | 28 ---------------------------- src/gpu/SDL_sysgpu.h | 1 - src/gpu/d3d12/SDL_gpu_d3d12.c | 29 ++++++++++++++++++++++++++++- src/gpu/metal/SDL_gpu_metal.m | 6 +++++- src/gpu/vulkan/SDL_gpu_vulkan.c | 5 ++++- 5 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index 9154c4d770..6a6b161cd0 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -517,7 +517,6 @@ void SDL_GPU_BlitCommon( static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props) { Uint32 i; - SDL_GPUShaderFormat format_flags = 0; const char *gpudriver; SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -526,25 +525,6 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props) return NULL; } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_PRIVATE; - } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_SPIRV; - } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_DXBC; - } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_DXIL; - } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_MSL; - } - if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) { - format_flags |= SDL_GPU_SHADERFORMAT_METALLIB; - } - gpudriver = SDL_GetHint(SDL_HINT_GPU_DRIVER); if (gpudriver == NULL) { gpudriver = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, NULL); @@ -554,10 +534,6 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props) if (gpudriver != NULL) { for (i = 0; backends[i]; i += 1) { if (SDL_strcasecmp(gpudriver, backends[i]->name) == 0) { - if (!(backends[i]->shader_formats & format_flags)) { - SDL_SetError("Required shader format for backend %s not provided!", gpudriver); - return NULL; - } if (backends[i]->PrepareDriver(_this, props)) { return backends[i]; } @@ -569,10 +545,6 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props) } for (i = 0; backends[i]; i += 1) { - if ((backends[i]->shader_formats & format_flags) == 0) { - // Don't select a backend which doesn't support the app's shaders. - continue; - } if (backends[i]->PrepareDriver(_this, props)) { return backends[i]; } diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h index d4f532fde6..ee7fd10f2f 100644 --- a/src/gpu/SDL_sysgpu.h +++ b/src/gpu/SDL_sysgpu.h @@ -1141,7 +1141,6 @@ struct SDL_GPUDevice typedef struct SDL_GPUBootstrap { const char *name; - const SDL_GPUShaderFormat shader_formats; bool (*PrepareDriver)(SDL_VideoDevice *_this, SDL_PropertiesID props); SDL_GPUDevice *(*CreateDevice)(bool debug_mode, bool prefer_low_power, SDL_PropertiesID props); } SDL_GPUBootstrap; diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 6ccb2de179..ca170089d9 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -8333,6 +8333,17 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props) IDXGIFactory6 *factory6; IDXGIAdapter1 *adapter; + // Early check to see if the app has _any_ D3D12 formats, if not we don't + // have to fuss with loading D3D in the first place. + bool has_dxbc = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOLEAN, false); + bool has_dxil = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOLEAN, false); + bool supports_dxil = false; + // TODO SM7: bool has_spirv = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false); + // TODO SM7: bool supports_spirv = false; + if (!has_dxbc && !has_dxil) { + return false; + } + // Can we load D3D12? d3d12Dll = SDL_LoadObject(D3D12_DLL); @@ -8427,6 +8438,18 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props) (void **)&device); if (SUCCEEDED(res)) { + D3D12_FEATURE_DATA_SHADER_MODEL shaderModel; + shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0; + + res = ID3D12Device_CheckFeatureSupport( + device, + D3D12_FEATURE_SHADER_MODEL, + &shaderModel, + sizeof(shaderModel)); + if (SUCCEEDED(res) && shaderModel.HighestShaderModel >= D3D_SHADER_MODEL_6_0) { + supports_dxil = true; + } + ID3D12Device_Release(device); } IDXGIAdapter1_Release(adapter); @@ -8435,6 +8458,11 @@ static bool D3D12_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props) SDL_UnloadObject(d3d12Dll); SDL_UnloadObject(dxgiDll); + if (!supports_dxil && !has_dxbc) { + SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: DXIL is not supported and DXBC is not being provided"); + return false; + } + if (FAILED(res)) { SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "D3D12: Could not create D3D12Device with feature level " D3D_FEATURE_LEVEL_CHOICE_STR); return false; @@ -9207,7 +9235,6 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD SDL_GPUBootstrap D3D12Driver = { "direct3d12", - SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_DXBC, D3D12_PrepareDriver, D3D12_CreateDevice }; diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 0d43a07f64..cd1d90acd2 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -4309,6 +4309,11 @@ static bool METAL_SupportsTextureFormat( static bool METAL_PrepareDriver(SDL_VideoDevice *this, SDL_PropertiesID props) { + if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOLEAN, false) && + !SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOLEAN, false)) { + return false; + } + if (@available(macOS 10.14, iOS 13.0, tvOS 13.0, *)) { return (this->Metal_CreateView != NULL); } @@ -4619,7 +4624,6 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD SDL_GPUBootstrap MetalDriver = { "metal", - SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB, METAL_PrepareDriver, METAL_CreateDevice }; diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index de0be4bdbe..9ed7ecad16 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -11605,6 +11605,10 @@ static bool VULKAN_PrepareDriver(SDL_VideoDevice *_this, SDL_PropertiesID props) VulkanRenderer *renderer; bool result = false; + if (!SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN, false)) { + return false; + } + if (_this->Vulkan_CreateSurface == NULL) { return false; } @@ -11987,7 +11991,6 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S SDL_GPUBootstrap VulkanDriver = { "vulkan", - SDL_GPU_SHADERFORMAT_SPIRV, VULKAN_PrepareDriver, VULKAN_CreateDevice };