Early Fragment Test

From OpenGL Wiki
Revision as of 15:34, 12 April 2015 by AlfonsesRenamerBot (talk | contribs) (Bot: Updating section links to use redirects.)
Jump to navigation Jump to search

Early Depth Test is a hardware feature supported by many GPUs that allow the depth test to proceed before fragment processing in the rendering pipeline, so long as certain conditions are met.

Usage

This is an optimization. If the fragment is behind other geometry, based on the depth values in the depth buffer, it saves performance to not bother executing the fragment shader. So the performance saved is only in the fragment shader.

The most effective way to use early depth test hardware is to run a depth-only pre-processing pass. This pass uses a minimal shader, one that transforms position values only. It masks color writes, so it only writes to the depth buffer.

This gives the best performance effect if your fragment shaders are expensive, or if you intend to use multiple passes across the geometry.

Limitations

The OpenGL Specification states that depth testing happens after fragment processing. A fragment's depth is part of the input to the fragment processing, and the fragment shader is free to modify this value or create an arbitrary depth. Thus, doing the depth test before fragment processing would make this impossible.

However, despite the wording of the spec, it is possible to do the depth test earlier in the pipeline. What the spec requires is that the depth test functions as if it were done after the fragment shader.

Thus the first restriction on early depth tests is that they cannot happen if the fragment shader writes gl_FragDepth. If the fragment shader modifies the depth, then the depth test must wait until after the fragment shader executes.

There can be other hardware-based limitations as well. For example, some hardware will not execute an early depth test if the (deprecated) alpha test is active, as these use the same hardware on that platform. Because this is a hardware-based optimization, OpenGL has no direct controls that will tell you if early depth testing will happen.

Similarly, if the fragment shader culls the fragment with the discard keyword, this can turn off early depth tests on some hardware. Again, even though the culling is conditional, any fragment shader that might discard will turn off early depth test on that hardware.

Explicit specification

Early Fragment Tests
Core in version 4.6
Core since version 4.2
Core ARB extension ARB_shader_image_load_store

More recent hardware can force early depth tests, using a special fragment shader layout qualifier:

layout(early_fragment_tests) in;

This will also perform early stencil tests.

There is a caveat with this. This feature cannot be used to violate the sanctity of the depth test. When this is activated, any writes to gl_FragDepth will be ignored. The value written to the depth buffer will be exactly what was tested against the depth buffer: the fragment's depth computed through rasterization.

This feature exists to ensure proper behavior when using Image Load Store or other incoherent memory writing. Fragments that fail the depth test will still perform their Image Load/Store operations, since the fragment shader that performed those operations successfully executed. However, with early fragment tests, those tests were run before the fragment shader. So this ensures that image load/store operations will only happen on fragments that pass the depth test.