This two fragment shaders that exhibit undefined behavior. In GLSL, it is undefined to use implicit or explicit derivatives in non-uniform control flow [1]. The SPIR-V produced by glslang contained similar undefined behavior, which results in incorrect codegen with the amdvlk's LLPC shader compiler, and produces visually incorrect image. This PR fixes this issue by hoisting the sampling so that it's executed before discarding. It's a simple fix and may not be the optimial way to resolve this issue. [1] https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf p. 137.
34 lines
986 B
GLSL
34 lines
986 B
GLSL
#version 450
|
|
|
|
layout (input_attachment_index = 0, binding = 1) uniform subpassInput samplerPositionDepth;
|
|
layout (binding = 2) uniform sampler2D samplerTexture;
|
|
|
|
layout (location = 0) in vec3 inColor;
|
|
layout (location = 1) in vec2 inUV;
|
|
|
|
layout (location = 0) out vec4 outColor;
|
|
|
|
layout (constant_id = 0) const float NEAR_PLANE = 0.1f;
|
|
layout (constant_id = 1) const float FAR_PLANE = 256.0f;
|
|
|
|
float linearDepth(float depth)
|
|
{
|
|
float z = depth * 2.0f - 1.0f;
|
|
return (2.0f * NEAR_PLANE * FAR_PLANE) / (FAR_PLANE + NEAR_PLANE - z * (FAR_PLANE - NEAR_PLANE));
|
|
}
|
|
|
|
void main ()
|
|
{
|
|
// Sample depth from deferred depth buffer and discard if obscured
|
|
float depth = subpassLoad(samplerPositionDepth).a;
|
|
|
|
// Save the sampled texture color before discarding.
|
|
// This is to avoid implicit derivatives in non-uniform control flow.
|
|
vec4 sampledColor = texture(samplerTexture, inUV);
|
|
if ((depth != 0.0) && (linearDepth(gl_FragCoord.z) > depth))
|
|
{
|
|
discard;
|
|
};
|
|
|
|
outColor = sampledColor;
|
|
}
|