Metal: Ensure explicit return after discard to eliminate differences in behaviour between GPUs.

Discard is not always treated as an explicit return and flow control can continue for required derivative calculations. This behaviour is different in Metal vs OpenGL. Adding return after discards ensures consistency in expectation as behaviour is well-defined.

Authored by Apple: Michael Parkin-White

Ref T96261

Reviewed By: fclem

Maniphest Tasks: T96261

Differential Revision: https://developer.blender.org/D17199
This commit is contained in:
Jason Fielder 2023-02-07 00:57:54 +01:00 committed by Clément Foucault
parent f152159101
commit 8703db393b
Notes: blender-bot 2023-05-22 14:36:19 +02:00
Referenced by issue #104659, 3.5.0 crashes on Mac Pro Intel with AMD GPUs on Cycles / GPU Compute (macOS Monterey)
Referenced by issue #104419, Unable to select anything in the viewport
Referenced by issue #96261, Metal Viewport
Referenced by issue #104915, Regression: Multires wireframes are displayed incomplete
Referenced by issue #107913, Hard Crash Opening Blender File With Library Overrides
15 changed files with 26 additions and 3 deletions

View File

@ -41,6 +41,7 @@ void main(void)
/* Outside of bokeh shape. Try to avoid overloading ROPs. */
if (max_v4(shapes) == 0.0) {
discard;
return;
}
if (!no_scatter_occlusion) {

View File

@ -226,6 +226,7 @@ void main()
if (depth == 1.0) {
discard;
return;
}
ivec2 texel = ivec2(gl_FragCoord.xy);
@ -235,6 +236,7 @@ void main()
if (max_v3(brdf) <= 0.0) {
discard;
return;
}
FragDepth = depth;

View File

@ -9,6 +9,7 @@ void main()
/* Discard outside the circle. */
if (dist_sqr > 1.0) {
discard;
return;
}
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));

View File

@ -8,6 +8,7 @@ void main()
/* Discard outside the circle. */
if (dist_sqr > 1.0) {
discard;
return;
}
vec3 view_nor = vec3(quadCoord, sqrt(max(0.0, 1.0 - dist_sqr)));

View File

@ -37,6 +37,7 @@ void main()
/* Outside of bokeh shape. Try to avoid overloading ROPs. */
if (max_v4(shapes) == 0.0) {
discard;
return;
}
if (!no_scatter_occlusion) {

View File

@ -80,6 +80,7 @@ void main()
float transparency = avg(g_transmittance);
if (transparency > random_threshold) {
discard;
return;
}
#endif

View File

@ -10,6 +10,7 @@ void main()
/* Discard if there is no edge. */
if (dot(out_edges, float2(1.0, 1.0)) == 0.0) {
discard;
return;
}
#elif SMAA_STAGE == 1

View File

@ -104,6 +104,7 @@ void main()
if (fragColor.a < 0.001) {
discard;
return;
}
}
@ -114,6 +115,7 @@ void main()
float scene_depth = texture(gpSceneDepthTexture, uvs).r;
if (gl_FragCoord.z > scene_depth) {
discard;
return;
}
/* FIXME(fclem): Grrr. This is bad for performance but it's the easiest way to not get
@ -121,6 +123,7 @@ void main()
float mask = texture(gpMaskTexture, uvs).r;
if (mask < 0.001) {
discard;
return;
}
/* We override the fragment depth using the fragment shader to ensure a constant value.

View File

@ -15,6 +15,7 @@ void main()
float depth = texelFetch(depth_texture, uvs_clamped, 0).r;
if (depth == 1.0) {
discard;
return;
}
vec4 tex_color = texelFetch(imageTexture, uvs_clamped - offset, 0);

View File

@ -18,6 +18,7 @@ void main()
gp_interp.thickness.x,
gp_interp.hardness) < 0.001) {
discard;
return;
}
if (!gpStrokeOrder3d) {

View File

@ -8,6 +8,7 @@ void main()
if (dist > 0.5) {
discard;
return;
}
/* Nice sphere falloff. */
float intensity = sqrt(1.0 - dist * 2.0) * 0.5 + 0.5;

View File

@ -8,6 +8,7 @@ void main()
/* Round point with jaggy edges. */
if (dist_squared > rad_squared) {
discard;
return;
}
#if defined(VERT)

View File

@ -7,6 +7,7 @@ void main()
* If we could get rid of it would be nice because of performance drain of discard. */
if (edgeStart.r == -1.0) {
discard;
return;
}
#ifndef SELECT_EDGES

View File

@ -9,6 +9,7 @@ void main()
/* Discard if there is no edge. */
if (dot(out_edges, float2(1.0, 1.0)) == 0.0) {
discard;
return;
}
#elif SMAA_STAGE == 1

View File

@ -777,8 +777,10 @@ float2 SMAALumaEdgeDetectionPS(float2 texcoord,
# ifndef SMAA_NO_DISCARD
# ifdef GPU_FRAGMENT_SHADER
// Then discard if there is no edge:
if (dot(edges, float2(1.0, 1.0)) == 0.0)
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
discard;
return float2(0.0, 0.0);
}
# endif
# endif
@ -847,8 +849,10 @@ float2 SMAAColorEdgeDetectionPS(float2 texcoord,
# ifndef SMAA_NO_DISCARD
# ifdef GPU_FRAGMENT_SHADER
// Then discard if there is no edge:
if (dot(edges, float2(1.0, 1.0)) == 0.0)
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
discard;
return float2(0.0, 0.0);
}
# endif
# endif
@ -895,8 +899,10 @@ float2 SMAADepthEdgeDetectionPS(float2 texcoord, float4 offset[3], SMAATexture2D
float2 edges = step(SMAA_DEPTH_THRESHOLD, delta);
# ifdef GPU_FRAGMENT_SHADER
if (dot(edges, float2(1.0, 1.0)) == 0.0)
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
discard;
return float2(0.0, 0.0);
}
# endif
return edges;