SPIRV-Cross/reference/shaders-msl/frag/frag-discard-checks-continue-block.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

50 lines
913 B
GLSL

#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct foo
{
int x;
};
struct main0_out
{
float4 fragColor [[color(0)]];
};
fragment main0_out main0(device foo& _24 [[buffer(0)]], float4 gl_FragCoord [[position]])
{
main0_out out = {};
bool gl_HelperInvocation = {};
gl_HelperInvocation = simd_is_helper_thread();
if (gl_FragCoord.y == 7.0)
{
gl_HelperInvocation = true, discard_fragment();
}
if (!gl_HelperInvocation)
{
_24.x = 0;
}
for (;;)
{
if (float(_24.x) < gl_FragCoord.x)
{
int _41 = _24.x;
int _43 = _41 + 1;
if (!gl_HelperInvocation)
{
_24.x = _43;
}
continue;
}
else
{
break;
}
}
out.fragColor = float4(float(_24.x), 0.0, 0.0, 1.0);
return out;
}