DXR conformance on an M1: test_raytracing passes, and DispatchRays goes indirect
vkd3d-proton's main D3D12 ray-tracing conformance test now passes all 1,826 of its checks on the D3D12-on-Metal layer on an M1 Max, and Dispatch
What changed
- vkd3d-proton
test_raytracingpasses. This is the broad DXR test from vkd3d-proton (the D3D12-on-Vulkan project whose test suite this project runs). In an earlier probe, 909 of its 1,826 checks failed. In this session's full run, 0 failed. The fixes:- static samplers declared in local root signatures (the arguments stored per shader record);
- exports that use different global root signatures in one pipeline;
- pipeline flags that skip triangles or procedural geometry;
- one rule from the spec: a ray that hits the edge shared by two triangles reports one hit, not two.
- Indirect DispatchRays.
ExecuteIndirectreplays commands whose arguments the GPU can write. For DispatchRays, a small GPU kernel copies each command's D3D12_DISPATCH_RAYS_DESC (shader-table addresses and a W×H×D grid) into that command's record and computes the threadgroup counts. A command over D3D12's limit of 2^30 rays gets zero threadgroups. New api test rt_indirect: 66 checks. - Review fixes. A later review found that the new root signature references broke the device's deduplication of identical root signatures and could release one twice. It also found that the indirect path skipped the ray limit. Both are fixed.

The interesting part
One subtest checks reference counts. The D3D12 docs say a pipeline state object holds its root signatures. The test expects the opposite: after the pipeline is created, the root signature's count is still 1. Its comment says native drivers behave that way (vkd3d-proton's d3d12_raytracing.c, line 1573). So the layer now keeps root signatures alive with an internal "hold" that the public count doesn't show.
The dead end: at first, the kernel chose the ray-generation record with raygen_size ? raygen : 0. In about 7 of 10 runs, every ray of test_raytracing_local_rs_static_sampler then missed, even rays aimed at opaque quads. The host now writes address 0 for an empty record, and the kernel doesn't branch. I don't know why the branch broke tracing.
Numbers
- Full run: 721 pass, 27 fail, 108 skip of 856 tests .
- It has 0 newly failing and 8 newly passing tests against this session's first run (713 / 27 / 115 of 855). The 8 are rt_indirect and seven vkd3d-proton
test_raytracing*tests.
- It has 0 newly failing and 8 newly passing tests against this session's first run (713 / 27 / 115 of 855). The 8 are rt_indirect and seven vkd3d-proton
- Checks: vkd3d-proton 23,882,841 passed and 3,800 failed, the same failures as before. The api suite passed 9,508 checks with none failing.
- pass
- fail
- skip
suite · share of each row's total
- vkd3d-proton (+18)455 pass, 18 fail, 104 skip of 577
- vkd3d (+6)177 pass, 9 fail, 4 skip of 190
- api (+4)55 pass, 0 fail, 0 skip of 55
- apps30 pass, 0 fail, 0 skip of 30
- samples4 pass, 0 fail, 0 skip of 4