CNA-BUG-094: SDL_GPU claims compute shaders and SPIR-V compute intake on every device, including Direct3D 12 and Metal drivers that cannot take its raw SPIR-V compute pipelines
Evidence basis: source-verified at the pinned commit; inferred from the source (the behaviour was not run); tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
SupportsComputeShadersEXT() and the SPIR-V compute-stage answer are true whenever a device exists, but compute pipelines still reach SDL_gpu as raw SPIR-V, which its Direct3D 12 and Metal drivers reject; ShaderEffect SPIR-V is now routed through the shader cross-compiler.
- Identifier
CNA-BUG-094- Category
- Bug
- Subsystem
- Graphics & renderers
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
c1c316b9(c1c316b9c7a846ce8002809c151fcd1af14942c9) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Inferred (strong): follows from the code, but the behaviour was not run
- Tests touching this area
- Yes: see Current tests
- Affected contract
- GraphicsDevice::SupportsCapability(GraphicsCapability::ComputeShaders) and GraphicsDevice::SupportsShaderLanguageEXT(SpirV, Compute) on SDL_GPU
Expected behaviour
IGraphicsRenderer::SupportsComputeShadersEXT() answers "whether this renderer really implements compute", and SupportsShaderLanguageEXT is true "only when the implemented shader intake consumes that exact pair". GraphicsDevice::SupportsCapability(ComputeShaders) is derived from the former precisely so that compute is never claimed by default.
Actual behaviour at TARGET
SdlGpuRenderer::SupportsComputeShadersEXT() returns device_ != nullptr, and SdlGpuRenderer::SupportsShaderLanguageEXT answers the compute stage with it. Stock shaders and, since AM4-068, ShaderEffect SPIR-V reach a non-SPIR-V driver through CreateRoutedSpirvShaderEXT, which uses SDL_shadercross when the device does not accept SPIR-V. The compute intake does not: SdlGpuComputeShaderRenderer::CompileProgram still creates the pipeline with SDL_GPU_SHADERFORMAT_SPIRV. With CNA_SDL_GPU_SHADERCROSS=ON, the default on Windows and macOS, the device may be created on SDL_gpu's Direct3D 12 or Metal driver; there both compute answers are true while a compute pipeline cannot be created from the raw SPIR-V. No public CNA API creates compute pipelines, so the effect is on callers that trust SupportsCapability(ComputeShaders) and on shader packages that select a SPIR-V compute variant.
Source locations
modules/renderers/sdl-gpu/src/SdlGpuRenderer.cpp— SdlGpuRenderer::SupportsComputeShadersEXT and SdlGpuRenderer::SupportsShaderLanguageEXTmodules/renderers/sdl-gpu/src/SdlGpuRenderer.cpp— CreateRoutedSpirvShaderEXT and CreateSdlGpuShaderEXT (the shadercross route the graphics stages use)modules/renderers/sdl-gpu/src/SdlGpuModern.cpp— SdlGpuComputeShaderRenderer::CompileProgram passes SDL_GPU_SHADERFORMAT_SPIRVcmake/RendererSelection.cmake— CNA_SDL_GPU_SHADERCROSS defaults ON on WIN32 and APPLE; SDL_gpu's Direct3D 12 driver and its Metal driver need translated shaders
Evidence
Checked by reading at c1c316b9; not executed; no compute run on SDL_gpu's Direct3D 12 driver or on its Metal driver exists for this entry. That SDL_gpu's Direct3D 12 and Metal drivers need translated shaders is CNA's own statement in cmake/RendererSelection.cmake and in the constructor's refusal when no driver accepts SPIR-V. On Linux SDL_gpu offers only its Vulkan driver, where both answers are correct and sdlgpu_smoke_test.cpp asserts them. Which driver SDL picks on a Windows host that offers both a Vulkan and a Direct3D 12 driver was not established; on macOS the device is Metal.
Narrowed at c1c316b9: 8a5e6e220 (AM4-068) routes ShaderEffect SPIR-V (and the libshaderc GLSL path) through CreateRoutedSpirvShaderEXT, the shadercross route the stock shaders already took, so the vertex and fragment SPIR-V answers now describe an intake the device can serve; SdlGpuComputeShaderRenderer::CompileProgram was not changed. Read at c1c316b9; not executed.
Focused reproduction
// Illustrative; not compiled or run for this entry. SDL_GPU build with CNA_SDL_GPU_SHADERCROSS=ON,
// on macOS (SDL_gpu's Metal driver) or on Windows with SDL_GPU_DRIVER=direct3d12.
using namespace Microsoft::Xna::Framework::Graphics;
GraphicsDevice device;
bool compute = device.SupportsCapability(CNA::GraphicsCapability::ComputeShaders); // true
bool spirv = device.SupportsShaderLanguageEXT(CNA::ShaderLanguageEXT::SpirV, CNA::ShaderStageEXT::Compute); // true
// Expected with truthful answers: both false on a driver that cannot create a pipeline from SPIR-V.
// Actual: SdlGpuComputeShaderRenderer::CompileProgram hands SDL raw SPIR-V, which the driver rejects.
Current tests
sdlgpu_smoke_test.cpp asserts that the device-level ComputeShaders and IndirectDraw answers equal the renderer's and are true, on Vulkan. No test creates a compute pipeline on a non-SPIR-V driver.
Regression test
Make the compute answers depend on SDL_GetGPUShaderFormats(device_) including SDL_GPU_SHADERFORMAT_SPIRV (or route the compute intake through SDL_shadercross as the graphics stages now are), and assert, on SDL_gpu's Direct3D 12 driver and on its Metal driver, that SupportsCapability(ComputeShaders) equals whether a trivial compute pipeline can be created.
Blast radius
SDL_GPU on a Direct3D 12 or Metal driver only (a shadercross build, the default on Windows and macOS): callers that trust SupportsCapability(ComputeShaders) and shader packages that select a SPIR-V compute variant. ShaderEffect SPIR-V payloads, Vulkan-driver SDL_GPU (every Linux build) and stock drawing are unaffected.
Workaround
On Windows, select SDL_gpu's Vulkan driver (SDL_GPU_DRIVER=vulkan) where one is installed; on macOS, do not rely on the ComputeShaders answer of SDL_GPU.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Graphics renderers: modern features
- Internals
- SDL_gpu renderer internals: shaders
- Known issues
- Bug index