summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PixelShaderGen.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2015-10-18 02:14:52 +1300
committerScott Mansell <phiren@gmail.com>2015-10-18 02:14:52 +1300
commit8b1138943d014bee7e11f0658010ac7e96c4b59d (patch)
tree10518776e68995f05dce4e12609fc05d8a61db5b /Source/Core/VideoCommon/PixelShaderGen.cpp
parent34d46d69109b6fc83986d0f1e1337da7887455df (diff)
parente7b2a22225b7d11f38dd045c990370df1daac61e (diff)
Merge pull request #3179 from phire/mesa-early-z
Support Conservative Depth as a fallback for Early Z (Mesa support for ZCompLoc)
Diffstat (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 8298d355f6..628d6343c8 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -306,14 +306,30 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
// Most importantly, it was not possible to write to the depth buffer without also writing
// a color value (unless color writing was disabled altogether).
- // OpenGL has a flag which allows the driver to still update the depth buffer if alpha
- // test fails. The driver isn't required to do this, but I (degasus) assume all of them do
- // because it's the much faster code path for the GPU.
+ // OpenGL 4.2 actually provides two extensions which can force an early z test:
+ // * ARB_image_load_store has 'layout(early_fragment_tests)' which forces the driver to do z and stencil tests early.
+ // * ARB_conservative_depth has 'layout(depth_unchanged) which signals to the driver that it can make optimisations
+ // which assume the pixel shader won't update the depth buffer.
+
+ // early_fragment_tests is the best option, as it requires the driver to do early-z and defines early-z excatly as
+ // we expect, with discard causing the shader to exit with only the depth buffer updated.
+
+ // Conservative depth's 'depth_unchanged' only hints to the driver that an early-z optimistaion can be made and
+ // doesn't define what will happen if we discard the fragment. But the way modern graphics hardware is implemented
+ // means it is not unreasonable to expect the the same behaviour as early_fragment_tests.
+ // We can also assume that if a driver has gone out of it's way to support conservative depth and not image_load_store
+ // as required by OpenGL 4.2 that it will be doing the optimisation.
+ // If the driver doesn't actually do an early z optimisation, ZCompLoc will be broken and depth will only be written
+ // if the alpha test passes.
+
+ // We support Conservative as a fallback, because many drivers based on Mesa haven't implemented all of the
+ // ARB_image_load_store extension yet.
// D3D11 also has a way to force the driver to enable early-z, so we're fine here.
if(ApiType == API_OPENGL)
{
- out.Write("layout(early_fragment_tests) in;\n");
+ // This is a #define which signals whatever early-z method the driver supports.
+ out.Write("FORCE_EARLY_Z; \n");
}
else
{