CNA-BUG-012: Two tests still encode the wrong occlusion-query expectation for SDL_GPU after the renderer was made truthful
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
SDL_GPU now reports OcclusionQuery false and refuses queries, but the shared capability test still expects true and SdlGpu_OcclusionQuery_Limitation expects a refusal message the public constructor never produces.
- Identifier
CNA-BUG-012- Category
- Bug
- Subsystem
- Testing & evidence
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- GraphicsDeviceCapabilityTest.SupportsOcclusionQuery / SupportsCustomEffects (ExpectedCapabilities()) and the SdlGpu_OcclusionQuery_Limitation CTest, against OcclusionQuery::OcclusionQuery(GraphicsDevice&)
Expected behaviour
A renderer that truthfully reports GraphicsCapability::OcclusionQuery as false and refuses OcclusionQuery construction should pass both the shared capability suite and its own limitation test. ExpectedCapabilities() in GraphicsDeviceCapabilityTests.cpp exists to state each renderer's accepted boundary ("Per-renderer arms below preserve each accepted capability boundary"), and SDLGPU-80 fixed SDL_GPU's: capability false, detailed profile Unsupported, and a System::NotSupportedException naming the SDL_gpu reason.
Actual behaviour at TARGET
The renderer half of the original defect is fixed (see Evidence). Two tests still disagree with it:
ExpectedCapabilities()has explicit arms only for OPENGLES2/WEBGL1, PORTABLEGL, FNA3D and SOFTWARE; every other renderer takesdefault: return {true, true, true}.SupportsOcclusionQuerytherefore expectstrueon SDL_GPU, whoseSdlGpuRenderer::SupportsCapabilityanswersfalse, andSupportsCustomEffectsexpectstrueon any SDL_GPU build withoutCNA_SDL_GPU_SHADER_EFFECTS(every Windows, Apple and Emscripten build, and Linux without libshaderc), where the answer isfalse. The same catch-all mis-describes METAL (no MRT, occlusion queries or custom effects by policy) and STUB (false for everything).sdlgpu_occlusionquery_limitation_test.cpprequireserror.what()to equal the message ofSdlGpuRenderer::CreateOcclusionQuery. The public constructor now refuses first, whenever the profile is Reach orSupportsCapability(OcclusionQuery)is false, with "OcclusionQuery is not supported by the active graphics profile and renderer." On SDL_GPU the capability is false, so the renderer's message is unreachable through the public constructor and the check "public OcclusionQuery construction throws the exact SDL_gpu limitation" fails.
Source locations
modules/graphics/tests/Microsoft/Xna/Framework/Graphics/GraphicsDeviceCapabilityTests.cpp— ExpectedCapabilities() default arm; SupportsOcclusionQuery and SupportsCustomEffectsmodules/renderers/sdl-gpu/examples/sdlgpu_occlusionquery_limitation_test.cpp— exact-message check on public OcclusionQuery constructionmodules/graphics/src/Xna/OcclusionQuery.cpp— OcclusionQuery::OcclusionQuery refuses on Reach or a false capability before calling CreateOcclusionQuerymodules/renderers/sdl-gpu/src/SdlGpuRenderer.cpp— SdlGpuRenderer::SupportsCapability (OcclusionQuery false) and SdlGpuRenderer::CreateOcclusionQuery (throws)modules/renderers/sdl-gpu/CMakeLists.txt— CNA_SDL_GPU_SHADER_EFFECTS only with a target-native libshaderc, never on Windows, Apple or Emscriptenmodules/renderers/webgpu/src/WebGPURenderer.cpp— WebGPURenderer::CreateOcclusionQuery, the fixed WebGPU halfplans/plan_pre_sdlgpu_closeout.md— PSG-0009: SdlGpu_OcclusionQuery_Limitation in the list of failing classic SDL_GPU CTestsplans/plan_street_sdlgpu.md— STREETS-0008: the same set, 26 failures, still failing in CNA's latest recorded run
Evidence
Checked by reading at 009d40f5; not executed. What is fixed: WebGPURenderer::CreateOcclusionQuery returns a real WebGPUOcclusionQueryRenderer (WEBGPU-84), pinned by WebGpuMrtOcclusionContract.OcclusionQueryCapabilityIsTrue and the WebGPU_OcclusionQuery pixel test; SDL_GPU answers the capability false and CreateOcclusionQuery throws (SDLGPU-80); and the public constructor refuses whenever the capability is false (SOFTWARE-199), so a null factory can no longer hand out a silent query. What survives is on the test side. CNA's own records corroborate the second item: plans/plan_sdlgpu.md records SdlGpu_OcclusionQuery_Limitation passing 5/5 when SDLGPU-80 landed on a line of history whose constructor still called the renderer factory directly; after both changes met, the test is in PSG-0009's list of classic SDL_GPU failures and remains among the 26 failures of the latest recorded run (STREETS-0008; one Radeon 780M under RADV, private compositor). The first item is by reading: no CNA record of GraphicsDeviceCapabilityTest.* under SDL_GPU after SDLGPU-80 was found, while CNA's records do show the same catch-all failing five cases under STUB (integration/BATCH_1_STABILIZATION.md).
Focused reproduction
# Not executed for this entry. An SDL_GPU build with tests, on a host with a Vulkan GPU and a display:
ctest --test-dir <sdl-gpu build> -R 'GraphicsDeviceCapabilityTest\.SupportsOcclusionQuery$|^SdlGpu_OcclusionQuery_Limitation$' --output-on-failure
Current tests
GraphicsDeviceCapabilityTests.cpp (per-renderer expectations; its MRT case already compares the capability with a real two-target bind), sdlgpu_occlusionquery_limitation_test.cpp, OcclusionQueryPixelCountPrecisionTests.cpp (skips when the capability is false) and, for the fixed WebGPU half, WebGpuMrtOcclusionContractTests.cpp and webgpu_occlusion_query_test.cpp. Nothing checks that ExpectedCapabilities() has an arm for every renderer whose answers differ from the catch-all.
Regression test
Give ExpectedCapabilities() explicit arms for SDL_GPU (occlusion false; custom effects equal to whether CNA_SDL_GPU_SHADER_EFFECTS is defined), METAL and STUB, and make the limitation test assert the public constructor's refusal (or have the constructor forward the renderer's reason). A structural guard in the style of TheMultipleRenderTargetCapabilityMatchesWhatBindingActuallyDoes: on a HiDef device, assert that SupportsCapability(OcclusionQuery) equals whether OcclusionQuery construction succeeds.
Blast radius
Test evidence only; renderer behaviour is correct. SDL_GPU runs of the shared capability suite and of the classic ^SdlGpu CTests report failures that are not renderer defects, which inflates the recorded SDL_GPU failure count and can hide real regressions among them. Renderers with explicit arms are unaffected.
Workaround
When triaging an SDL_GPU run, treat these two failures as test defects.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Graphics renderers: capability reporting
- Maintainer workflow
- Fix a renderer bug: prove it
- Tests and validation
- Test architecture: GPU tests
- Known issues
- Bug index