Fix 107322: MacOS/ATI Crash When Starting Eevee #109358

Merged
Jeroen Bakker merged 2 commits from Jeroen-Bakker/blender:macos-raytrace-infinitive-loop into blender-v3.6-release 2023-06-26 14:12:51 +02:00
2 changed files with 16 additions and 8 deletions

View File

@ -98,6 +98,9 @@ float occlusion_pow(float a, float b)
#endif
/* Return horizon angle cosine. */
#if (defined(GPU_METAL) && defined(GPU_ATI))
__attribute__((noinline))
#endif
float search_horizon(vec3 vI,
vec3 vP,
float noise,
@ -118,10 +121,12 @@ float search_horizon(vec3 vI,
}
Jeroen-Bakker marked this conversation as resolved Outdated

sample_count needs to be declared as int. Better do the conversion out of the loop const int i_sample_count = int(sample_count)

`sample_count` needs to be declared as int. Better do the conversion out of the loop `const int i_sample_count = int(sample_count)`
float prev_time, time = 0.0;
for (float iter = 0.0; time < ssray.max_time && iter < sample_count; iter++) {
Jeroen-Bakker marked this conversation as resolved Outdated

My apologies @Jeroen-Bakker , after testing the patch locally, one omission was that we also need to tag the function with no inline, though this should only be done for AMD platforms on Metal. Without this, the crash can still occur for certain material variants it appears.

I hope this is okay to include.

raytrace_lib.glsl

#ifdef METAL_AMD_RAYTRACE_WORKAROUND
__attribute__((noinline))
#endif
bool raytrace(Ray ray,
              RayTraceParameters params,
              const bool discard_backface,
              const bool allow_self_intersection,
              out vec3 hit_position)
{

and

#if (defined(GPU_METAL) && defined(GPU_ATI))
__attribute__((noinline))
#endif
float search_horizon(vec3 vI,
                     vec3 vP,
                     float noise,
                     ScreenSpaceRay ssray,
                     sampler2D depth_tx,
                     const float inverted,
                     float radius,
                     const float sample_count)
{
My apologies @Jeroen-Bakker , after testing the patch locally, one omission was that we also need to tag the function with no inline, though this should only be done for AMD platforms on Metal. Without this, the crash can still occur for certain material variants it appears. I hope this is okay to include. raytrace_lib.glsl ``` #ifdef METAL_AMD_RAYTRACE_WORKAROUND __attribute__((noinline)) #endif bool raytrace(Ray ray, RayTraceParameters params, const bool discard_backface, const bool allow_self_intersection, out vec3 hit_position) { ``` and ``` #if (defined(GPU_METAL) && defined(GPU_ATI)) __attribute__((noinline)) #endif float search_horizon(vec3 vI, vec3 vP, float noise, ScreenSpaceRay ssray, sampler2D depth_tx, const float inverted, float radius, const float sample_count) { ```
int i_sample_count = int(sample_count);
Jeroen-Bakker marked this conversation as resolved Outdated

iter needs to be explicitly converted to float here.

`iter` needs to be explicitly converted to float here.
for (int iter = 0; time < ssray.max_time && iter < i_sample_count; iter++) {
prev_time = time;
/* Gives us good precision at center and ensure we cross at least one pixel per iteration. */
time = 1.0 + iter + sqr((iter + noise) / sample_count) * ssray.max_time;
float fl_iter = float(iter);
time = 1.0 + fl_iter + sqr((fl_iter + noise) / sample_count) * ssray.max_time;
float stride = time - prev_time;
float lod = (log2(stride) - noise) / (1.0 + aoQuality);

View File

@ -105,6 +105,9 @@ struct RayTraceParameters {
/* Returns true on hit. */
/* TODO(fclem): remove the back-face check and do it the SSR resolve code. */
#ifdef METAL_AMD_RAYTRACE_WORKAROUND
__attribute__((noinline))
#endif
bool raytrace(Ray ray,
RayTraceParameters params,
const bool discard_backface,
@ -137,9 +140,9 @@ bool raytrace(Ray ray,
#ifdef METAL_AMD_RAYTRACE_WORKAROUND
bool hit_failsafe = true;
#endif
Jeroen-Bakker marked this conversation as resolved Outdated

iter needs to be explicitly converted to float here.

`iter` needs to be explicitly converted to float here.
const float max_steps = 255.0;
for (float iter = 1.0; !hit && (time < ssray.max_time) && (iter < max_steps); iter++) {
float stride = 1.0 + iter * params.trace_quality;
const int max_steps = 255;
for (int iter = 1; !hit && (time < ssray.max_time) && (iter < max_steps); iter++) {
float stride = 1.0 + float(iter) * params.trace_quality;
float lod = log2(stride) * lod_fac;
prev_time = time;
@ -210,9 +213,9 @@ bool raytrace_planar(Ray ray, RayTraceParameters params, int planar_ref_id, out
/* On very sharp reflections, the ray can be perfectly aligned with the view direction
* making the tracing useless. Bypass tracing in this case. */
bool hit = false;
Jeroen-Bakker marked this conversation as resolved Outdated

iter needs to be explicitly converted to float here.

`iter` needs to be explicitly converted to float here.
const float max_steps = 255.0;
for (float iter = 1.0; !hit && (time < ssray.max_time) && (iter < max_steps); iter++) {
float stride = 1.0 + iter * params.trace_quality;
const int max_steps = 255;
for (int iter = 1; !hit && (time < ssray.max_time) && (iter < max_steps); iter++) {
float stride = 1.0 + float(iter) * params.trace_quality;
prev_time = time;
prev_delta = delta;