KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.
Apache License 2.0
4.76k stars 419 forks source link

Enforce depth write to post fragment execution when attachment is used as input and output #2232

Closed aitor-lunarg closed 3 months ago

aitor-lunarg commented 4 months ago

Failing CTS tests:

dEQP-VK.rasterization.rasterization_order_attachment_access.depth.samples_1.multi_draw_barriers
dEQP-VK.rasterization.rasterization_order_attachment_access.stencil.samples_1.multi_draw_barriers
dEQP-VK.rasterization.rasterization_order_attachment_access.stencil.samples_2.multi_draw_barriers

These tests write to the same attachment in succession and checks that the write happens after fragment execution. However, Metal, for depth attachment under certain conditions (that are met by the test) writes the value before fragment execution which leads to failing the tests.

Solution is to enforce the depth write to post fragment execution. The way I found to accomplish this is by adding a pass through write of the depth value. Equivalent of the following GLSL code in Metal: gl_FragDepth = gl_FragCoord.z;

I couldn't find anything in the Metal specification about graphic pipeline's stage execution order nor synchronization dependencies between them, but I'm inclined to think that the failure of these tests imply there may be an oversight on Metal drivers.

For Vulkan spec text on the issue, please refer to https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/5087

In the short term, I believe implementing the enforced depth write will fix the issue for now, but we may find ourselves in the future having to find a different workaround, or if we are lucky Metal fixes this issue.