Description
Looking to enable tests around depth clipping and clamping in Dawn, there seems to be yet another inconsistency between APIs.
Because the frag_depth should always be clamped to the viewport, then @builtin(frag_depth)
implies that MTLDepthClipMode.clamp
is used. @kainino0x previously made this great table, but experimental results show that Metal with MTLDepthClipMode.clamp
doesn't do clipping of the fragment at the rasterization stage if @builtin(frag_depth)
is used.
More precisely, the following WGSL code with MTLDepthClipMode.Clamp
(and trivially the pipeline from it) draws a point on Metal which prevents implementing unclippedDepth = false
with frag_depth
like on the other APIs:
@vertex fn vs() -> @builtin(position) vec4<f32> {
return vec4<f32>(0.0, 0.0, 5.0, 1.0);
}
@fragment fn fs() -> @builtin(frag_depth) f32 {
return 0.5;
}
The way to fix this inconsistency is to pass the viewport bounds to the shader and either:
- Use
MTLDepthClipMode.clamp
and discard at the start of the FS if the position is outside of the viewport. - Use
MTLDepthClipMode.clip
and clamp the resulting frag_depth. (what we opted to do for Vulkan).
However since this changes what's in the investigation table, maybe we need to revisit the exact depth clipping behavior?