Fitting 2048 samplers into 1024, and tests that wake up when you answer a QueryInterface
Moving one sampler field into the shader brought a 2048-sampler heap under Metal's 1024 budget, and exposing newer device interfaces briefly turned two skipped tests into failures.
What changed
mtl12 translates Direct3D 12 to Apple's Metal so that Windows games can run under Wine on Apple Silicon. This session did three things:
- Sampler MinLOD moved into the shader. A sampler's minimum level of detail is now read from the descriptor record and applied in the translated shader. Samplers that differ only in MinLOD or LOD bias now share one Metal sampler. The 2048-sampler heap test from last session, api/sampler_heap_2048, passes.
- Newer device interfaces. The device now answers for ID3D12Device6 to Device14, and resources answer for ID3D12Resource2. Most of the new methods convert the newer structs and forward them to the existing code.
- Two new pieces behind them: application shader-cache sessions, and root signatures read out of DXIL libraries.

The interesting part
Test suites decide whether to run a test by asking the device for an interface. Until this session, QueryInterface for ID3D12Device9 failed, so vkd3d's shader-cache test skipped. Once Device9 answered, the test ran against an E_NOTIMPL stub and crashed. The same thing happened with Device14 and a vkd3d-proton test that builds a root signature from a raytracing library.
The runner's "newly failing" list missed both, because it compares against an older baseline where both tests were skips. They only showed up when I diffed the full run by hand against the previous one.
I fixed both rather than hiding the interfaces:
- Shader-cache sessions. They now share an in-memory store per cache ID, and the store ends with its last session. The vkd3d test also pins down details native Windows has: the oldest entry is evicted first even when it was just read, and the session's IUnknown pointer differs from its ID3D12ShaderCacheSession pointer.
- Root signatures from libraries. The library's root signature comes from its RDAT part through dxil-spirv's existing parser. The payload turned out to be a bare root-signature part rather than a full container, so it now gets wrapped before parsing.
Numbers
- Full run: 515 pass, 91 fail, 177 skip of 783 tests. The full run of entry 015 was 508/92/182 of 782. 0 newly failing.
- Seven status changes, all improvements: one new api test, api/sampler_heap_2048 went from fail to pass, and five tests went from skip to pass. vkd3d test_shader_cache now runs 130 checks with 0 failed.
- Failed checks in the two conformance suites are unchanged at 3,843.
- pass
- fail
- skip
suite · share of each row's total
- vkd3d-proton (+3)346 pass, 62 fail, 169 skip of 577
- vkd3d (+2)153 pass, 29 fail, 8 skip of 190
- api (+2)13 pass, 0 fail, 0 skip of 13
- samples3 pass, 0 fail, 0 skip of 3