Metal: Improve AMD EEVEE Performance #104743

Closed
Jason Fielder wants to merge 3 commits from Jason-Fielder/blender:MetalAMDPerformanceEEVEE_2 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 75 additions and 0 deletions
Showing only changes of commit 184345e885 - Show all commits

View File

@ -119,6 +119,22 @@ Closure closure_eval(ClosureReflection reflection)
return closure; return closure;
} }
CLOSURE_EVAL_FUNCTION_DECLARE_1(GlossyBSDFAlways, Glossy)
Closure closure_eval_always(ClosureReflection reflection)

Change closure_eval_always to be an overload of closure_eval with an optional const bool parameter for ssr output: closure_eval(ClosureReflection reflection, const bool do_ssr_output)

Change `closure_eval_always` to be an overload of `closure_eval` with an optional const bool parameter for ssr output: `closure_eval(ClosureReflection reflection, const bool do_ssr_output)`
{
/* Glue with the old system. */
CLOSURE_VARS_DECLARE_1(Glossy);
in_Glossy_0.N = reflection.N;
in_Glossy_0.roughness = reflection.roughness;
CLOSURE_EVAL_FUNCTION_1(GlossyBSDF, Glossy);
Closure closure = CLOSURE_DEFAULT;
closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight;
return closure;
}
CLOSURE_EVAL_FUNCTION_DECLARE_1(RefractionBSDF, Refraction) CLOSURE_EVAL_FUNCTION_DECLARE_1(RefractionBSDF, Refraction)
Closure closure_eval(ClosureRefraction refraction) Closure closure_eval(ClosureRefraction refraction)
{ {
@ -155,6 +171,13 @@ Closure closure_eval(ClosureTransparency transparency)
CLOSURE_EVAL_FUNCTION_DECLARE_2(GlassBSDF, Glossy, Refraction) CLOSURE_EVAL_FUNCTION_DECLARE_2(GlassBSDF, Glossy, Refraction)
Closure closure_eval(ClosureReflection reflection, ClosureRefraction refraction) Closure closure_eval(ClosureReflection reflection, ClosureRefraction refraction)
{ {
#if defined(DO_SPLIT_CLOSURE_EVAL)
Closure closure = closure_eval(refraction);
Closure closure_reflection = closure_eval(reflection);
closure.radiance += closure_reflection.radiance;
return closure;
#else
/* Glue with the old system. */ /* Glue with the old system. */
CLOSURE_VARS_DECLARE_2(Glossy, Refraction); CLOSURE_VARS_DECLARE_2(Glossy, Refraction);
@ -172,12 +195,19 @@ Closure closure_eval(ClosureReflection reflection, ClosureRefraction refraction)
closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight; closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight;
} }
return closure; return closure;
#endif
} }
/* Dielectric BSDF */ /* Dielectric BSDF */
CLOSURE_EVAL_FUNCTION_DECLARE_2(DielectricBSDF, Diffuse, Glossy) CLOSURE_EVAL_FUNCTION_DECLARE_2(DielectricBSDF, Diffuse, Glossy)
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection) Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
{ {
#if defined(DO_SPLIT_CLOSURE_EVAL)
Closure closure = closure_eval(diffuse);
Closure closure_reflection = closure_eval(reflection);
closure.radiance += closure_reflection.radiance;
return closure;
#else
/* Glue with the old system. */ /* Glue with the old system. */
CLOSURE_VARS_DECLARE_2(Diffuse, Glossy); CLOSURE_VARS_DECLARE_2(Diffuse, Glossy);
@ -198,6 +228,7 @@ Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight; closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight;
} }
return closure; return closure;
#endif
} }
/* Specular BSDF */ /* Specular BSDF */
@ -206,6 +237,13 @@ Closure closure_eval(ClosureDiffuse diffuse,
ClosureReflection reflection, ClosureReflection reflection,
ClosureReflection clearcoat) ClosureReflection clearcoat)
{ {
#if defined(DO_SPLIT_CLOSURE_EVAL)
Closure closure = closure_eval(diffuse);
Closure closure_reflection = closure_eval(reflection);
Closure closure_clearcoat = closure_eval_always(clearcoat);
closure.radiance += closure_reflection.radiance + closure_clearcoat.radiance;
return closure;
#else
/* Glue with the old system. */ /* Glue with the old system. */
CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy); CLOSURE_VARS_DECLARE_3(Diffuse, Glossy, Glossy);
@ -229,6 +267,7 @@ Closure closure_eval(ClosureDiffuse diffuse,
closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight; closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight;
} }
return closure; return closure;
#endif
} }
/* Principled BSDF */ /* Principled BSDF */
@ -238,6 +277,15 @@ Closure closure_eval(ClosureDiffuse diffuse,
ClosureReflection clearcoat, ClosureReflection clearcoat,
ClosureRefraction refraction) ClosureRefraction refraction)
{ {
#if defined(DO_SPLIT_CLOSURE_EVAL)
Closure closure = closure_eval(diffuse);
Closure closure_reflection = closure_eval(reflection);
Closure closure_clearcoat = closure_eval_always(clearcoat);
Closure closure_refraction = closure_eval(refraction);
closure.radiance += closure_reflection.radiance + closure_clearcoat.radiance +
closure_refraction.radiance;
return closure;
#else
/* Glue with the old system. */ /* Glue with the old system. */
CLOSURE_VARS_DECLARE_4(Diffuse, Glossy, Glossy, Refraction); CLOSURE_VARS_DECLARE_4(Diffuse, Glossy, Glossy, Refraction);
@ -263,11 +311,18 @@ Closure closure_eval(ClosureDiffuse diffuse,
closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight; closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight;
} }
return closure; return closure;
#endif
} }
CLOSURE_EVAL_FUNCTION_DECLARE_2(PrincipledBSDFMetalClearCoat, Glossy, Glossy) CLOSURE_EVAL_FUNCTION_DECLARE_2(PrincipledBSDFMetalClearCoat, Glossy, Glossy)
Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat) Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
{ {
#if defined(DO_SPLIT_CLOSURE_EVAL)
Closure closure = closure_eval(clearcoat);
Closure closure_reflection = closure_eval(reflection);
closure.radiance += closure_reflection.radiance;
return closure;
#else
/* Glue with the old system. */ /* Glue with the old system. */
CLOSURE_VARS_DECLARE_2(Glossy, Glossy); CLOSURE_VARS_DECLARE_2(Glossy, Glossy);
@ -284,6 +339,7 @@ Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight; closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight;
} }
return closure; return closure;
#endif
} }
/* Not supported for surface shaders. */ /* Not supported for surface shaders. */

View File

@ -17,6 +17,10 @@ Closure closure_eval(ClosureReflection reflection)
{ {
return CLOSURE_DEFAULT; return CLOSURE_DEFAULT;
} }
Closure closure_eval_always(ClosureReflection reflection)
{
return CLOSURE_DEFAULT;
}
Closure closure_eval(ClosureRefraction refraction) Closure closure_eval(ClosureRefraction refraction)
{ {
return CLOSURE_DEFAULT; return CLOSURE_DEFAULT;

View File

@ -53,6 +53,7 @@ vec3 coordinate_incoming(vec3 P);
Closure closure_eval(ClosureDiffuse diffuse); Closure closure_eval(ClosureDiffuse diffuse);
Closure closure_eval(ClosureTranslucent translucent); Closure closure_eval(ClosureTranslucent translucent);
Closure closure_eval(ClosureReflection reflection); Closure closure_eval(ClosureReflection reflection);
Closure closure_eval_always(ClosureReflection reflection);
Closure closure_eval(ClosureRefraction refraction); Closure closure_eval(ClosureRefraction refraction);
Closure closure_eval(ClosureEmission emission); Closure closure_eval(ClosureEmission emission);
Closure closure_eval(ClosureTransparency transparency); Closure closure_eval(ClosureTransparency transparency);

View File

@ -16,6 +16,14 @@ typedef struct CommonUniformBlock CommonUniformBlock;
# endif # endif
#endif #endif
/* NOTE: AMD-based macOS platforms experience performance and correctness issues with EEVEE
* material closure evaluation. Using singular closure evaluation, rather than the compound
* function calls reduces register overflow, by limiting the simultaneous number of live
* registers used by the virtual GPU function stack. */
#if (defined(GPU_METAL) && defined(GPU_ATI))
# define DO_SPLIT_CLOSURE_EVAL 1
#endif
struct CommonUniformBlock { struct CommonUniformBlock {
mat4 pastViewProjectionMatrix; mat4 pastViewProjectionMatrix;
vec4 hizUvScale; /* To correct mip level texel misalignment */ vec4 hizUvScale; /* To correct mip level texel misalignment */

View File

@ -92,6 +92,12 @@ Closure closure_eval(ClosureReflection reflection)
return Closure(0); return Closure(0);
} }
Closure closure_eval_always(ClosureReflection reflection)
{
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, reflection);
return Closure(0);
}
Closure closure_eval(ClosureRefraction refraction) Closure closure_eval(ClosureRefraction refraction)
{ {
SELECT_CLOSURE(g_refraction_data, g_refraction_rand, refraction); SELECT_CLOSURE(g_refraction_data, g_refraction_rand, refraction);