SPIRV-Cross/shaders-msl/frag/frag-discard-checks.discard-checks.msl23.frag
Chip Davis aa5a8c482e MSL: Prevent stores to storage resources in discarded fragments.
Some Metal devices have a bug where storage resources can still be
written to even if the fragment is discarded. This is obviously a bug in
Metal, but bothering Apple to fix it will only fix it for newer
versions; therefore, a workaround is needed for older versions. I have
made this an option so that, in case the bug is ever fixed, the
workaround can be disabled.

This workaround is simple: if a fragment shader may discard its fragment
and writes to a storage resource, a variable representing the
`HelperInvocation` built-in is created and passed to all functions. The
flag is checked on all resource writes; writes do not occur when
`HelperInvocation` is `true`. This relies on the earlier workaround to
update `HelperInvocation` when the fragment is discarded.

Fixes at least 3 failures in the CTS.
2022-11-20 01:29:41 -08:00

33 lines
688 B
GLSL

#version 450
layout(set=0, binding=0, std430) buffer foo_t
{
float x;
uint y;
} foo;
layout(r32ui, set=0, binding=1) uniform uimage2D bar;
layout(location=0) out vec4 fragColor;
vec4 frag_body() {
foo.x = 1.0f;
atomicExchange(foo.y, 0);
if (int(gl_FragCoord.x) == 3)
discard;
imageStore(bar, ivec2(gl_FragCoord.xy), uvec4(1));
atomicAdd(foo.y, 42);
imageAtomicOr(bar, ivec2(gl_FragCoord.xy), 0x3e);
atomicAnd(foo.y, 0xffff);
atomicXor(foo.y, 0xffffff00);
atomicMin(foo.y, 1);
imageAtomicMax(bar, ivec2(gl_FragCoord.xy), 100);
imageAtomicCompSwap(bar, ivec2(gl_FragCoord.xy), 100, 42);
return vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
void main() {
fragColor = frag_body();
}