MOOR security

Dieser Eintrag ist auf Englisch verfasst.

Three formats the tables say Metal can write, and one that a buffer actually takes

Entry 076871 of 965 tests pass

mtl12 now tells D3D12 programs they can write BGRA8 pixels from compute shaders; two other formats Apple's tables list as writable were left out, because on an M1 their buffer stores vanish.

What changed

A UAV (unordered access view, a view a shader can write to at arbitrary positions) of a "typed" format lets a shader store a float4 and have the GPU convert it into the format's bits. D3D12 makes a few formats optional for this. A program asks CheckFeatureSupport whether, say, B8G8R8A8_UNORM (8-bit blue, green, red, alpha) supports typed UAVs. Dawn's bgra8unorm-storage feature asks exactly that, and vkd3d-proton's UAV clear test skips the formats a driver says no to.

mtl12 had said no to B8G8R8A8_UNORM, A8_UNORM (alpha only) and R9G9B9E5_SHAREDEXP (three 9-bit mantissas sharing one exponent). The commit that did so gave no evidence. Apple's Metal feature set tables list textures of all three formats as writable on Apple GPUs. So I wrote a test first: api/uav_store_formats stores four distinct values per format from a compute shader, through a 2D texture view and through a buffer view, then clears half the texels and reads the bytes back.

What the texture and buffer stores did for each format, and what is claimed.Metal feature set tables (Apple7): which formats textures can write → format; format → texture store: ok buffer store: ok (BGRA8); format → texture store: ok buffer store: dropped (0) (A8); format → texture store: ok buffer store: dropped (0) (RGB9E5); texture store: ok buffer store: ok → claimed: TYPED_UAV + UAV_TYPED_STORE; texture store: ok buffer store: dropped (0) → not claimed: the bits cover buffer views too; texture store: ok buffer store: dropped (0) → not claimed: the bits cover buffer views tooMetal feature set tables(Apple7): which formatstextures can writeformattexture store: okbuffer store: oktexture store: okbuffer store: dropped (0)texture store: okbuffer store: dropped (0)claimed: TYPED_UAV+ UAV_TYPED_STOREnot claimed: the bitscover buffer views tooBGRA8A8RGB9E5
What the texture and buffer stores did for each format, and what is claimed. (Mermaid source)

The interesting part

All three formats passed as textures. A8 failed as a buffer: every stored texel stayed 0. Metal backs D3D12 typed buffer views with "texture buffers" (a texture view onto a buffer's bytes). A temporary print showed the A8 texture buffer was created with the right width and usage. Storing the same value in all four components still wrote nothing, so the store is not landing in the wrong channel either. The UAV clear of the same view worked, because mtl12 packs clears on the CPU.

A later review of the change asked why RGB9E5 had no buffer case. Its buffer stores are dropped too. Apple's tables don't list RGB9E5 texture buffers at all. They do list A8 ones as writable, and BGRA8 ones as read-only, yet BGRA8 is the one whose buffer stores work.

D3D12's support bits make no distinction between texture and buffer views. Claiming A8 or RGB9E5 would promise buffer stores that silently disappear, so only BGRA8 is claimed. The test checks that the other two stay unclaimed. The RGB9E5 clear packer I had written was removed again, because nothing can reach it.

Numbers

  • vkd3d-proton test_clear_unordered_access_view_image: 15 skipped cases before, 9 after (6 for A8, 3 for RGB9E5). It executed 33,437 checks before and 35,033 after.
  • Full run: 871 of 965 tests pass, 26 fail, 68 skip; 869 of 964 in the previous full run. Newly failing: none.
Tests by suite at the end of this entry: 871 of 965 pass (data as CSV)
  • pass
  • fail
  • skip

suite · share of each row's total

  1. vkd3d-proton499 pass, 13 fail, 65 skip of 577
  2. vkd3d178 pass, 9 fail, 3 skip of 190
  3. api (+2)94 pass, 0 fail, 0 skip of 94
  4. apps80 pass, 0 fail, 0 skip of 80
  5. wine-dxgi16 pass, 4 fail, 0 skip of 20
  6. samples4 pass, 0 fail, 0 skip of 4
vkd3d-proton test_clear_unordered_access_view_image: skipped cases by format (data as CSV)
  • before
  • after

format · skipped cases

  1. B8G8R8A8_UNORM6 before, 0 after
  2. A8_UNORM6 before, 6 after
  3. R9G9B9E5_SHAREDEXP3 before, 3 after