CNA-GAP-013: METAL refuses a large part of the graphics API until it has macOS evidence: MRT, custom effects, occlusion queries, instancing, multi-stream input, back-buffer readback and several sampler/blend states
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.
MetalRenderer throws NotSupportedException for MRT, custom effects, occlusion queries, instancing, multi-stream input, back-buffer readback and some sampler/blend states, and applies every MSAA request as none.
- Identifier
CNA-GAP-013- 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
- GraphicsDevice and resource APIs on the METAL renderer
Expected behaviour
A renderer identity is expected to support the XNA HiDef surface or refuse clearly; METAL chooses explicit refusal pending evidence.
Actual behaviour at TARGET
MetalRenderer.mm throws System::NotSupportedException, mostly with 'disabled until the adapted renderer has passing macOS ... evidence' wording, for: SetRenderTargets with more than one target; CreateEffectRenderer (ShaderEffect), SpriteBatch custom effects and custom-effect 3D draws; CreateOcclusionQuery; instancing and multi-stream vertex input; and ReadBackbuffer ('the historical macOS test run returned clear-color-only data after real draws'). It also throws, with plainer wording ('not implemented' and 'currently supports only'), for a sampler MaxMipLevel or MipMapLevelOfDetailBias other than 0 and for blend states with partial colour-write masks or a non-default MultiSampleMask. MetalAppliedMultiSampleCount in MetalPolicy.hpp returns 0 for every request, so every MSAA request is clamped to none; this is reported rather than hidden (the MultiSampleAntiAliasing capability is false and the applied count is 0). MetalSupportsCapability reports false for MRT, occlusion queries, custom effects, multi-stream input and instancing, so the capability flags do not lie. The renderer builds only on macOS: the metal-macos-ci.yml workflow builds it on macos-14 and runs the ^Metal tests, while Linux hosts build only the portable policy tests.
Source locations
modules/renderers/metal/src/MetalRenderer.mm— NotSupportedException refusals (SetRenderTargets, CreateEffectRenderer, CreateOcclusionQuery, ReadBackbuffer, ApplySamplerMipState, ApplyBlendState, draw stream policy)modules/renderers/metal/include/CNA/Internal/Renderers/Metal/MetalPolicy.hpp— MetalAppliedMultiSampleCount returns 0modules/renderers/metal/examples/CMakeLists.txt— the three registered Metal testsmodules/renderers/metal/examples/metal_spritebatch_customeffect_test.cpp— the unregistered test
Evidence
Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. The refusals are explicit and documented in the messages; macOS was not available.
Independent re-verification: Checked by reading the named sources at 009d40f5; nothing was built or executed for this entry. The refusals are explicit and documented in the messages; macOS was not available. Tests: Metal_Capabilities asserts the refused features are reported unsupported, Metal_PortableHelpers pins the pure policy decisions (draw-stream policy, blend write state, applied MSAA count), and Metal_Smoke covers the supported contract (see CNA-VGAP-024); no test runs the throwing MetalRenderer paths themselves.
Independently reported as CNA-VGAP-050 (folded into this entry by the adversarial audit): The Metal examples register only Metal_PortableHelpers, Metal_Smoke and Metal_Capabilities; the four-check custom-effect pixel test is referenced nowhere, and MetalRenderer::CreateEffectRenderer refuses custom effects until macOS evidence exists.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
Metal_Smoke, Metal_Capabilities and Metal_PortableHelpers exist (see CNA-VGAP-024); none exercises the refused features.
Regression test
Each feature's enabling change should come with a macOS pixel test, as the refusal messages require.
Blast radius
Any game using the refused features on macOS with the METAL renderer; the other macOS-capable renderers are unaffected.
Workaround
Use another renderer on macOS (for example the GL family) where these features are needed.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Internals
- Draw-call internals: other backends
- Known issues
- Functional gap index