MOOR security

Dieser Eintrag ist auf Englisch verfasst.

Sample masks, LOD clamps and clear colours Metal doesn't handle

Entry 012482 of 774 tests pass

Eleven more D3D12 conformance tests pass on Metal after moving sample masks, minimum-LOD clamps and clear-colour rules into the layer.

What changed

This session closed small gaps between D3D12 and Metal, one test at a time:

  • Stage interfaces are now checked when a pipeline is created. A pixel shader input with no matching vertex shader output is rejected, as D3D12 does, instead of failing later in Metal.
  • Sample mask. This is a pipeline bitmask that switches off individual samples of a multisampled pixel. Metal pipelines don't have one, so the generated pixel shader ANDs it into its coverage output.
  • Minimum LOD clamp. This view setting stops sampling from picking mips finer than a given level. Metal views don't have it, so the descriptor stores the clamp and the shader applies it.
  • Static-sampler LOD bias is now baked into the shader.
  • Heap and resource validation covers the rules for shared and cross-adapter heaps and for row-major textures.
  • Read-only depth views. Each pipeline now builds four Metal depth-stencil states, one for each combination of read-only depth and read-only stencil. A draw picks the one that matches the bound view.
Scene samplemask: the same star through SampleMask 0x1, 0x3, 0x7, 0xF on 4x MSAA, resolved
Gallery scene samplemask: the same star through SampleMask 0x1, 0x3, 0x7, 0xF on 4x MSAA, resolved. All scenes in the gallery

The interesting part

Clear colours were the surprise. D3D12 converts a clear colour the way it converts a shader output: integer formats truncate, saturate to the component's range and turn NaN into 0. Metal's clear colour is four doubles and isn't saturated at all. On my machine, FLT_MAX cleared to float16 infinity, INF cleared to 0 in UINT formats, and values of 2³¹ and above cleared to 0x80000000 in SINT formats. The fix converts the colour before it reaches Metal, and the clear command carries integer bits for integer formats. The vkd3d-proton extreme-values test had 17 failing checks before and none after.

One attempt failed. vkd3d's test_unbounded_resource_arrays writes a buffer through one descriptor and reads it back through another descriptor for the same memory, in the same shader thread. On Metal the read returns stale data. Making the read go through a read-write texture didn't help, so the change wasn't committed.

Clear colours are converted the way a shader output would be before Metal clears.raw Metal ✘ vs D3D12 and mtl12 now ✔: FLT_MAX on float16: infinity ✘ · 65504 ✔, INF on R32_UINT: 0 ✘ · 0xffffffff ✔, 2³¹ on R32_SINT: 0x80000000 ✘ · 0x7fffffff ✔; ClearRenderTargetView colour (4 floats) → mtl12 converts it like a shader output: truncate, saturate, NaN → 0; mtl12 converts it like a shader output: truncate, saturate, NaN → 0 → integer bits for integer formats; integer bits for integer formats → Metal clear; mtl12 converts it like a shader output: truncate, saturate, NaN → 0: raw Metal ✘ vs D3D12 and mtl12 now ✔raw Metal ✘ vs D3D12 and mtl12 now ✔ClearRenderTargetViewcolour (4 floats)mtl12 converts it like a shader output:truncate, saturate, NaN → 0integer bits for integer formatsMetal clearFLT_MAX on float16: infinity ✘ · 65504 ✔INF on R32_UINT: 0 ✘ · 0xffffffff ✔2³¹ on R32_SINT: 0x80000000 ✘ · 0x7fffffff ✔
Clear colours are converted the way a shader output would be before Metal clears. (Mermaid source)

Numbers

  • Full suite: 482 pass, 102 fail, 190 skip of 774, up from 471 / 112 / 190 of 773. 11 tests newly pass, one of them a new test, and none newly fail. Failed checks went from 4,111 to 3,861.
  • test_shader_io_mismatch: 71 → 57 failed checks.
  • Static-sampler bias test: 8 of 11 cases failed before, and all pass after.
  • test_deferred_clears_dsv_layout: 24 failed checks before, 0 after.
Tests by suite at the end of entry 012: 482 of 774 pass (data as CSV)
  • pass
  • fail
  • skip

suite · share of each row's total

  1. vkd3d-proton (+9)329 pass, 69 fail, 179 skip of 577
  2. vkd3d (+1)146 pass, 33 fail, 11 skip of 190
  3. api (+1)4 pass, 0 fail, 0 skip of 4
  4. samples3 pass, 0 fail, 0 skip of 3