MOOR security

Dieser Eintrag ist auf Englisch verfasst.

Fitting 2048 samplers into 1024, and tests that wake up when you answer a QueryInterface

Entry 016515 of 783 tests pass

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.
Scene minlod: nine flat-colour mips sampled with MinLOD 0-7 per column: a staircase
Gallery scene minlod: nine flat-colour mips sampled with MinLOD 0-7 per column: a staircase. All scenes in the gallery

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.
What stays in the Metal sampler, and what the translated shader now applies itself.D3D12 sampler → descriptor record: MinLOD, MipLODBias; D3D12 sampler → Metal key: filter, address, anisotropy, comparison, border, reduction, MaxLOD; descriptor record: MinLOD, MipLODBias → translated shader applies them per sample; Metal key: filter, address, anisotropy, comparison, border, reduction, MaxLOD → sampler cache: one MTLSamplerState per distinct key; sampler cache: one MTLSamplerState per distinct key → 2048 D3D12 samplers fit in Metal's budget of 1024D3D12 samplerdescriptor record:MinLOD, MipLODBiasMetal key: filter, address,anisotropy, comparison, border,reduction, MaxLODtranslated shaderapplies them per samplesampler cache: one MTLSamplerStateper distinct key2048 D3D12 samplers fit inMetal's budget of 1024
What stays in the Metal sampler, and what the translated shader now applies itself. (Mermaid source)

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.
Tests by suite at the end of entry 016: 515 of 783 pass (data as CSV)
  • pass
  • fail
  • skip

suite · share of each row's total

  1. vkd3d-proton (+3)346 pass, 62 fail, 169 skip of 577
  2. vkd3d (+2)153 pass, 29 fail, 8 skip of 190
  3. api (+2)13 pass, 0 fail, 0 skip of 13
  4. samples3 pass, 0 fail, 0 skip of 3