Does WebGPU Support 'Early Fragment Test'?

159 views
Skip to first unread message

Philip Taylor

unread,
Sep 16, 2024, 3:13:44 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
Hi, I'm writing a shader that assumes fragments will be discarded before the fragment shader is invoked, if they fail the early fragment test. 

It is based on the following algorithm:

The technique is using the fragment shader to populate a visibility buffer. Only fragments passing the early depth test would be evaluated and they would update a visibility buffer.

The algorithm is very simple, but in my case, it looks like _all_ fragments are going through the fragment shader stage and, and potentially being discarded after. I'm not sure when the depth test is being performed.
I would assume that 'early-z discard' would eliminate these fragments, and I think that the algorithm relies on this feature to work.

I can't see any configuration of early-z rejection in WebGPU, so I would assume it's on by default.
Am I making an incorrect assumption here?

--
Philip TAYLOR
CTO, Zea Inc.
Montréal, Québec
The contents of this e-mail are confidential with all rights reserved to the author. It is illegal to use or divulge this information without authorization. If you have received this e-mail by mistake, please notify me immediately by replying to the e-mail. 

Philip Taylor

unread,
Sep 16, 2024, 3:47:24 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin

I think I might have stumbled across my answer...
My fragment shader is writing to a visibility buffer(not a render target), and it appears that, at least with Vulkan, this behariod causes early fragment tests to be disabled.

@group(0) @binding(2) var<storage, read_write> visibility: array<u32>;
@fragment fn fs(vsOut: VSOutput) -> FSOutput {
  var output : FSOutput;
  output.color = ...;
 
  visibility[vsOut.index] = 1;//
  return output;
}

https://docs.vulkan.org/features/latest/features/proposals/VK_AMD_shader_early_and_late_fragment_tests.html#_problem_statement

"However, if the shader also writes to storage resources, no such optimization is possible due to the predictability requirements of the specification."

Is this behavior inherited by WebGPU? Any comments?

Brandon Jones

unread,
Sep 16, 2024, 3:47:44 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
Yes, WebGPU will do early Z rejection by default. This is disabled if the fragment shader alters the frag_depth builtin.

Relatedly, you can also do depth-only rendering that skips fragment processing entirely by omitting the `fragment` options while creating a render pipeline. At that point the vertex shaders will run and the resulting depth will output to the depth buffer but no color values will be computed, giving you an efficient way to populate the depth buffer early, which then takes advantage of that early Z rejection in later passes.

--Brandon

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/webgl-dev-list/CAC7g9xQi11qY%3DEFkmYLEffGd_AObL3adEhUSftFX6EVMugViTA%40mail.gmail.com.

Philip Taylor

unread,
Sep 16, 2024, 3:59:41 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
Thanks Brandon, I assumed early-z rejection would be working, and my shader is trivial, (not writing to frag depth, but writing out to a buffer). 
The technique I am implementing relies on early-z rejection, but so far it appears that all fragments are passing the early tests giving incorrect results.


On Mon, Sep 16, 2024 at 3:47 PM 'Brandon Jones' via WebGL Dev List <webgl-d...@googlegroups.com> wrote:
Yes, WebGPU will do early Z rejection by default. This is disabled if the fragment shader alters the frag_depth builtin.

Relatedly, you can also do depth-only rendering that skips fragment processing entirely by omitting the `fragment` options while creating a render pipeline. At that point the vertex shaders will run and the resulting depth will output to the depth buffer but no color values will be computed, giving you an efficient way to populate the depth buffer early, which then takes advantage of that early Z rejection in later passes.

--Brandon

On Mon, Sep 16, 2024 at 12:13 PM 'Philip Taylor' via WebGL Dev List <webgl-d...@googlegroups.com> wrote:
Hi, I'm writing a shader that assumes fragments will be discarded before the fragment shader is invoked, if they fail the early fragment test. 

It is based on the following algorithm:

The technique is using the fragment shader to populate a visibility buffer. Only fragments passing the early depth test would be evaluated and they would update a visibility buffer.

The algorithm is very simple, but in my case, it looks like _all_ fragments are going through the fragment shader stage and, and potentially being discarded after. I'm not sure when the depth test is being performed.
I would assume that 'early-z discard' would eliminate these fragments, and I think that the algorithm relies on this feature to work.

I can't see any configuration of early-z rejection in WebGPU, so I would assume it's on by default.
Am I making an incorrect assumption here?

--
Philip TAYLOR
CTO, Zea Inc.
Montréal, Québec
The contents of this e-mail are confidential with all rights reserved to the author. It is illegal to use or divulge this information without authorization. If you have received this e-mail by mistake, please notify me immediately by replying to the e-mail. 

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/webgl-dev-list/CAC7g9xQi11qY%3DEFkmYLEffGd_AObL3adEhUSftFX6EVMugViTA%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.

Brandon Jones

unread,
Sep 16, 2024, 4:12:22 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
As you pointed out in your earlier reply, it may be that anything else that causes the fragment shader to have observable side effects (such as writing to a storage buffer/texture) could also cause the fragment shader to ignore early Z rejection. That's not something that we've explicitly stated in the spec, and it's worth checking to see if the working group has discussed it before. The Vulkan reference you linked will be helpful if we haven't addressed it already, thanks!

Regardless, WebGPU's behavior is going to be "Whatever common denominator we can find or force between the native APIs." so if that's simply the default behavior of Vulkan then there's a good likelihood that will be the default behavior of WebGPU as well.

--Brandon

Philip Taylor

unread,
Sep 16, 2024, 4:17:24 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
Thanks! I've found this thread requesting explicit control of early fragment operations, but it doesn't look like it was picked up:

I will have to figure out an alternative solution.

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/webgl-dev-list/CAC7g9xS_UFfSfEmRrX-QtKf1aSSH5K-V2WX%3DTkHHznzqS3R36w%40mail.gmail.com.

--
You received this message because you are subscribed to the Google Groups "WebGL Dev List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to webgl-dev-lis...@googlegroups.com.

Brandon Jones

unread,
Sep 16, 2024, 4:26:27 PM9/16/24
to webgl-d...@googlegroups.com, Gabriel Beaudin
I've filed an issue here to ensure this is made clear in the spec one way or the other: https://github.com/gpuweb/gpuweb/issues/4878

But yes, in your case you may have to find an alternative given that it seems like the expected behavior is likely that storage writes will force all fragments to run. We may be able to develop an extension to control that, but if we do it's going to be a while before it's available.

--Brandon

Reply all
Reply to author
Forward
0 new messages