CNA-GAP-021: DIRECTX9 BasicEffect reaches only 12 of its 32 shader variants; other combinations throw 'no matching CNA vertex layout'
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.
DirectX9Renderer::DrawBasicEffectEXT accepts only four fixed stride and flag shapes (stride 16 vertex colour, 20 texture, 24 vertex colour plus texture, 32 lit plus texture), which reach 12 of BasicEffect's 32 ShaderIndex values; position-only, position+normal and colour+normal inputs, including untextured per-pixel lighting, throw.
- Identifier
CNA-GAP-021- Category
- Functional gap
- Subsystem
- Graphics & renderers
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- BasicEffect draws on DIRECTX9
Expected behaviour
XNA's BasicEffect selects one of 32 shader variants from its lighting, texture, vertex-colour, fog and per-pixel flags and draws any matching vertex format.
Actual behaviour at TARGET
In D3D9EffectDraw.cpp, DirectX9Renderer::DrawBasicEffectEXT switches on the vertex stride and accepts only 16, 20, 24 and 32, each with one fixed lighting / vertex-colour / texture combination; any other stride or flag combination throws std::runtime_error naming 'no matching CNA vertex layout (plan_dx9.md D9-82b)'. The drawable ShaderIndex values are 2-7, 12/13, 20/21 and 28/29 (12 of 32); untextured vertex, one-light and per-pixel lighting and position-only drawing are refused. The file's header comment documents this as an honest gap, but its statement that the renderer has only five stride-keyed declarations (16/20/24/32/52) is stale: VertexElementsForStrideD3D9 in D3D9VertexDeclarations.cpp also declares strides 28, 48, 56, 60, 68 and 80 (dual-texture, PBR and skinned-colour paths), none of which BasicEffect accepts.
Source locations
modules/renderers/directx9/src/D3D9EffectDraw.cpp— header comment and DirectX9Renderer::DrawBasicEffectEXT layout checks
Evidence
Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry.
Independent re-verification: Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. The refusal is pinned by Check F of directx9_drawex_test.cpp (registered as the DirectX9_DrawEx CTest under the DIRECTX9 label; the Windows D3D CI matrix builds DIRECTX11, DIRECTX12 and DIRECT2D only).
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
DIRECTX9 stock-effect fixtures cover the drawable variants.
Regression test
One fixture per missing vertex shape once declarations are added.
Blast radius
DIRECTX9 games drawing VertexPositionNormal (lit, untextured) or position-only geometry with BasicEffect.
Workaround
Use vertex formats with texture coordinates (for example VertexPositionNormalTexture).
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Deep dives
- Direct3D 9 fidelity: effect reach
- Known issues
- Functional gap index