diff --git a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp index ab919a0cad..a8d3100098 100644 --- a/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp +++ b/GPU/Vulkan/FragmentShaderGeneratorVulkan.cpp @@ -36,7 +36,9 @@ static const char *vulkan_glsl_preamble = "#version 450\n" "#extension GL_ARB_separate_shader_objects : enable\n" - "#extension GL_ARB_shading_language_420pack : enable\n\n"; + "#extension GL_ARB_shading_language_420pack : enable\n" + "#extension GL_ARB_conservative_depth : enable\n" + "#extension GL_ARB_shader_image_load_store : enable\n\n"; #define WRITE p+=sprintf @@ -80,6 +82,13 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer) { bool isModeClear = id.Bit(FS_BIT_CLEARMODE); const char *shading = doFlatShading ? "flat" : ""; + bool earlyFragmentTests = !enableAlphaTest && !enableColorTest && !gstate_c.Supports(GPU_ROUND_FRAGMENT_DEPTH_TO_16BIT); + + if (earlyFragmentTests) { + WRITE(p, "layout (early_fragment_tests) in;\n"); + } else { + WRITE(p, "layout (depth_unchanged) out float gl_FragDepth;\n"); + } WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseUBO {\n%s} base;\n", ub_baseStr); if (doTexture) { @@ -570,6 +579,10 @@ bool GenerateVulkanGLSLFragmentShader(const FShaderID &id, char *buffer) { WRITE(p, " z = (1.0/65535.0) * floor(z * 65535.0);\n"); } WRITE(p, " gl_FragDepth = z;\n"); + } else if (!earlyFragmentTests) { + // Adreno (and possibly MESA/others) apply early frag tests even with discard in the shader. + // Writing depth prevents the bug, even with depth_unchanged specified. + WRITE(p, " gl_FragDepth = gl_FragCoord.z;\n"); } WRITE(p, "}\n"); diff --git a/GPU/Vulkan/StencilBufferVulkan.cpp b/GPU/Vulkan/StencilBufferVulkan.cpp index 7ce1e00fe5..0ec2195e79 100644 --- a/GPU/Vulkan/StencilBufferVulkan.cpp +++ b/GPU/Vulkan/StencilBufferVulkan.cpp @@ -32,15 +32,17 @@ static const char *stencil_fs = R"(#version 450 #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable +#extension GL_ARB_conservative_depth : enable +layout (depth_unchanged) out float gl_FragDepth; layout (binding = 0) uniform sampler2D tex; -layout(push_constant) uniform params { +layout (push_constant) uniform params { int u_stencilValue; }; layout (location = 0) in vec2 v_texcoord0; layout (location = 0) out vec4 fragColor0; void main() { - gl_FragDepth = 0.0; + gl_FragDepth = gl_FragCoord.z; if (u_stencilValue == 0) { fragColor0 = vec4(0.0);