From da3f99ae5f91c437ddb47ea4b97aeeda242c4d59 Mon Sep 17 00:00:00 2001 From: Michael Parkin-White Date: Mon, 13 Feb 2023 14:13:20 +0000 Subject: [PATCH] Metal/EEVEE: Resolve rendering artifacts in EEVEE with Intel GPUs on macOS. Intel GPUs exhibit a number of rendering artifacts. The most substantial being incorrect resolve of reflections. Splitting the reflections_resolve shader into two passes, one for SSR and one for light probes ensures correct rendering and optimal performance on this GPU. Also resolves an artifact with ambient occlusion wherein the pow(a, b) function causes excessive precision loss. Using an alternative method for power calculation on these platforms resolves the issues. Authored by Apple: Michael Parkin-White Ref T96261 --- .../draw/engines/eevee/eevee_private.h | 7 ++ .../engines/eevee/eevee_screen_raytrace.c | 119 ++++++++++++++---- .../draw/engines/eevee/eevee_shaders.cc | 26 +++- .../eevee/shaders/ambient_occlusion_lib.glsl | 21 +++- .../shaders/closure_eval_glossy_lib.glsl | 17 +++ .../effect_reflection_resolve_frag.glsl | 34 ++++- .../infos/eevee_legacy_effects_info.hh | 13 ++ 7 files changed, 205 insertions(+), 32 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 136f14afbb3..92ab093267b 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -242,6 +242,8 @@ typedef struct EEVEE_PassList { struct DRWPass *volumetric_accum_ps; struct DRWPass *ssr_raytrace; struct DRWPass *ssr_resolve; + struct DRWPass *ssr_resolve_probe; + struct DRWPass *ssr_resolve_refl; struct DRWPass *sss_blur_ps; struct DRWPass *sss_resolve_ps; struct DRWPass *sss_translucency_ps; @@ -700,6 +702,9 @@ typedef struct EEVEE_EffectsInfo { struct GPUTexture *ssr_specrough_input; struct GPUTexture *ssr_hit_output; struct GPUTexture *ssr_hit_depth; + /* Intel devices require a split execution due to shader issue */ + bool use_split_ssr_pass; + /* Temporal Anti Aliasing */ int taa_reproject_sample; int taa_current_sample; @@ -1208,6 +1213,8 @@ struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_sh_get(void); struct GPUShader *EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void); struct GPUShader *EEVEE_shaders_effect_reflection_trace_sh_get(void); struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_probe_sh_get(void); +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_refl_sh_get(void); struct GPUShader *EEVEE_shaders_renderpasses_post_process_sh_get(void); struct GPUShader *EEVEE_shaders_cryptomatte_sh_get(bool is_hair); struct GPUShader *EEVEE_shaders_shadow_sh_get(void); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index 0d0e551f3dc..37eec1ab18c 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -14,6 +14,7 @@ #include "DEG_depsgraph_query.h" +#include "GPU_platform.h" #include "GPU_texture.h" #include "eevee_private.h" @@ -86,6 +87,12 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_depth), }); + /* NOTE(Metal): Intel GPUs rendering with Metal require the reflections pass to be split + * into two separate phases. This reduces the individual complexity of each shader + * invocation. */ + effects->use_split_ssr_pass = GPU_type_matches_ex( + GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL); + return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_RADIANCE_BUFFER | EFFECT_DOUBLE_BUFFER | ((use_refraction) ? EFFECT_REFRACT : 0); } @@ -145,30 +152,76 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT; - DRW_PASS_CREATE(psl->ssr_resolve, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); - grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve); - DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); - DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input); - DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex); - DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool); - DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); - DRW_shgroup_uniform_texture_ref_ex(grp, "hitBuffer", &effects->ssr_hit_output, no_filter); - DRW_shgroup_uniform_texture_ref_ex(grp, "hitDepth", &effects->ssr_hit_depth, no_filter); - DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->filtered_radiance); - DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); - DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool); - DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); - DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); - DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); - DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); - DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); - DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + if (effects->use_split_ssr_pass) { + /* Prepare passes for split reflections resolve variant. */ + for (int i = 0; i < 2; i++) { + if (i == 0) { + /* Prepare Reflection Probes resolve pass. */ + struct GPUShader *resolve_shader_probe = + EEVEE_shaders_effect_reflection_resolve_probe_sh_get(); + DRW_PASS_CREATE(psl->ssr_resolve_probe, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); + grp = DRW_shgroup_create(resolve_shader_probe, psl->ssr_resolve_probe); + } + else if (i == 1) { + /* Prepare SSR resolve pass. */ + struct GPUShader *resolve_shader_refl = + EEVEE_shaders_effect_reflection_resolve_refl_sh_get(); + DRW_PASS_CREATE(psl->ssr_resolve_refl, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); + grp = DRW_shgroup_create(resolve_shader_refl, psl->ssr_resolve_refl); + } + + DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input); + DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex); + DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool); + DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); + DRW_shgroup_uniform_texture_ref_ex(grp, "hitBuffer", &effects->ssr_hit_output, no_filter); + DRW_shgroup_uniform_texture_ref_ex(grp, "hitDepth", &effects->ssr_hit_depth, no_filter); + DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->filtered_radiance); + DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool); + DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); + DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + } + } + else { + /* Prepare standard reflections resolve pass. */ + DRW_PASS_CREATE(psl->ssr_resolve, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD); + grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve); + + DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); + DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input); + DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex); + DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool); + DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth); + DRW_shgroup_uniform_texture_ref_ex(grp, "hitBuffer", &effects->ssr_hit_output, no_filter); + DRW_shgroup_uniform_texture_ref_ex(grp, "hitDepth", &effects->ssr_hit_depth, no_filter); + DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->filtered_radiance); + DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); + DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool); + DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool); + DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); + DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1); + DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); + } } } @@ -205,7 +258,15 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v EEVEE_effects_downsample_radiance_buffer(vedata, txl->color_double_buffer); GPU_framebuffer_bind(fbl->main_color_fb); - DRW_draw_pass(psl->ssr_resolve); + + if (effects->use_split_ssr_pass) { + /* Trace reflections for probes and SSR independently */ + DRW_draw_pass(psl->ssr_resolve_probe); + DRW_draw_pass(psl->ssr_resolve_refl); + } + else { + DRW_draw_pass(psl->ssr_resolve); + } /* Restore */ GPU_framebuffer_bind(fbl->main_fb); @@ -244,6 +305,12 @@ void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear); } - DRW_draw_pass(psl->ssr_resolve); + if (effects->use_split_ssr_pass) { + DRW_draw_pass(psl->ssr_resolve_probe); + DRW_draw_pass(psl->ssr_resolve_refl); + } + else { + DRW_draw_pass(psl->ssr_resolve); + } } } diff --git a/source/blender/draw/engines/eevee/eevee_shaders.cc b/source/blender/draw/engines/eevee/eevee_shaders.cc index 3b3ff33308c..4cb147cf712 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.cc +++ b/source/blender/draw/engines/eevee/eevee_shaders.cc @@ -113,6 +113,8 @@ static struct { /* Screen Space Reflection */ struct GPUShader *reflection_trace; struct GPUShader *reflection_resolve; + struct GPUShader *reflection_resolve_probe; + struct GPUShader *reflection_resolve_raytrace; /* Shadows */ struct GPUShader *shadow_sh; @@ -658,6 +660,24 @@ struct GPUShader *EEVEE_shaders_effect_reflection_resolve_sh_get(void) return e_data.reflection_resolve; } +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_probe_sh_get(void) +{ + if (e_data.reflection_resolve_probe == NULL) { + e_data.reflection_resolve_probe = DRW_shader_create_from_info_name( + "eevee_legacy_effect_reflection_resolve_probe"); + } + return e_data.reflection_resolve_probe; +} + +struct GPUShader *EEVEE_shaders_effect_reflection_resolve_refl_sh_get(void) +{ + if (e_data.reflection_resolve_raytrace == NULL) { + e_data.reflection_resolve_raytrace = DRW_shader_create_from_info_name( + "eevee_legacy_effect_reflection_resolve_ssr"); + } + return e_data.reflection_resolve_raytrace; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1281,8 +1301,8 @@ static char *eevee_get_defines(int options) /* Global EEVEE defines included for CreateInfo shaders via `engine_eevee_shared_defines.h` in * eevee_legacy_common_lib CreateInfo. */ - /* Defines which affect bindings are instead injected via CreateInfo permutations. To specify new - * permutations, references to GPUShaderCreateInfo variants should be fetched in: + /* Defines which affect bindings are instead injected via CreateInfo permutations. To specify + * new permutations, references to GPUShaderCreateInfo variants should be fetched in: * `eevee_get_vert/geom/frag_info(..)` * * CreateInfo's for EEVEE materials are declared in: @@ -1495,6 +1515,8 @@ void EEVEE_shaders_free(void) } DRW_SHADER_FREE_SAFE(e_data.reflection_trace); DRW_SHADER_FREE_SAFE(e_data.reflection_resolve); + DRW_SHADER_FREE_SAFE(e_data.reflection_resolve_probe); + DRW_SHADER_FREE_SAFE(e_data.reflection_resolve_raytrace); DRW_SHADER_LIB_FREE_SAFE(e_data.lib); if (e_data.default_world) { diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 32748a71038..23f6f046c37 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -82,6 +82,21 @@ vec2 get_ao_dir(float jitter) return vec2(cos(jitter), sin(jitter)); } +/* Certain intel drivers on macOS lose precision, resulting in rendering artifacts, + * when using standard pow(A, B) function. + * Using logarithmic identity provides higher precision results. */ +#if defined(GPU_INTEL) && defined(OS_MAC) +float occlusion_pow(float a, float b) +{ + return exp(b * log(a)); +} +#else +float occlusion_pow(float a, float b) +{ + return pow(a, b); +} +#endif + /* Return horizon angle cosine. */ float search_horizon(vec3 vI, vec3 vP, @@ -327,7 +342,7 @@ float diffuse_occlusion(OcclusionData data, vec3 V, vec3 N, vec3 Ng) float visibility; occlusion_eval(data, V, N, Ng, 0.0, visibility, unused_error, unused); /* Scale by user factor */ - visibility = pow(saturate(visibility), aoFactor); + visibility = occlusion_pow(saturate(visibility), aoFactor); return visibility; } @@ -340,7 +355,7 @@ float diffuse_occlusion( visibility = gtao_multibounce(visibility, albedo); /* Scale by user factor */ - visibility = pow(saturate(visibility), aoFactor); + visibility = occlusion_pow(saturate(visibility), aoFactor); return visibility; } @@ -404,7 +419,7 @@ float specular_occlusion( visibility = mix(specular_occlusion, 1.0, tmp); /* Scale by user factor */ - visibility = pow(saturate(visibility), aoFactor); + visibility = occlusion_pow(saturate(visibility), aoFactor); return visibility; } diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl index 83b3fafddcb..b16fb266f34 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl @@ -88,10 +88,13 @@ void closure_Glossy_light_eval(ClosureInputGlossy cl_in, ClosureLightData light, inout ClosureOutputGlossy cl_out) { +/* Ensure specular light contribution only gets applied once when running split pass */ +#ifndef RESOLVE_SSR float radiance = light_specular(light.data, cl_eval.ltc_mat, cl_in.N, cl_common.V, light.L); radiance *= cl_eval.ltc_brdf_scale; cl_out.radiance += light.data.l_color * (light.data.l_spec * light.vis * light.contact_shadow * radiance); +#endif } void closure_Glossy_planar_eval(ClosureInputGlossy cl_in, @@ -117,9 +120,12 @@ void closure_Glossy_cubemap_eval(ClosureInputGlossy cl_in, ClosureCubemapData cube, inout ClosureOutputGlossy cl_out) { +/* Ensure cubemap probes contribution only gets applied once when running split pass */ +#ifndef RESOLVE_SSR vec3 probe_radiance = probe_evaluate_cube( cube.id, cl_common.P, cl_eval.probe_sampling_dir, cl_in.roughness); cl_out.radiance += cube.attenuation * probe_radiance; +#endif } void closure_Glossy_indirect_end(ClosureInputGlossy cl_in, @@ -127,6 +133,8 @@ void closure_Glossy_indirect_end(ClosureInputGlossy cl_in, ClosureEvalCommon cl_common, inout ClosureOutputGlossy cl_out) { +/* Ensure specular contribution only gets applied once when running split pass */ +#ifndef RESOLVE_SSR /* If not enough light has been accumulated from probes, use the world specular cubemap * to fill the remaining energy needed. */ if (specToggle && cl_common.specular_accum > 0.0) { @@ -136,8 +144,17 @@ void closure_Glossy_indirect_end(ClosureInputGlossy cl_in, /* Apply occlusion on distant lighting. */ cl_out.radiance *= cl_eval.spec_occlusion; +#endif /* Apply Raytrace reflections after occlusion since they are direct, local reflections. */ +#if defined(RESOLVE_PROBE) + /* NO OP - output base radiance*/ +#elif defined(RESOLVE_SSR) + /* Output only raytrace radiance */ + cl_out.radiance = cl_eval.raytrace_radiance; +#else + /* Standard resolve */ cl_out.radiance += cl_eval.raytrace_radiance; +#endif } void closure_Glossy_eval_end(ClosureInputGlossy cl_in, diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index de3a22b37dd..41310fd2e67 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -39,7 +39,13 @@ vec4 ssr_get_scene_color_and_mask(vec3 hit_vP, int planar_index, float mip) color = textureLod(probePlanars, vec3(uv, planar_index), mip).rgb; } else { + + /* Do not sample scene buffer if running probe pass in split reflection mode. */ +#ifndef RESOLVE_PROBE color = textureLod(colorBuffer, uv * hizUvScale.xy, mip).rgb; +#else + color = vec3(0.0); +#endif } /* Clamped brightness. */ @@ -223,10 +229,26 @@ CLOSURE_EVAL_FUNCTION_DECLARE_1(ssr_resolve, Glossy) void main() { float depth = textureLod(maxzBuffer, uvcoordsvar.xy * hizUvScale.xy, 0.0).r; - +#if defined(GPU_INTEL) && defined(GPU_METAL) + float factor = 1.0f; +#endif if (depth == 1.0) { +#if defined(GPU_INTEL) && defined(GPU_METAL) + /* Divergent code execution (and sampling) causes corruption due to undefined + * derivative/sampling behaviour, on Intel GPUs. Using a mask factor to ensure shaders do not + * diverge and only the final result is masked. */ + factor = 0.0f; +#else + /* Note: In the Metal API, prior to Metal 2.3, Discard is not an explicit return and can + * produce undefined behaviour. This is especially prominent with derivatives if control-flow + * divergence is present. + * + * Adding a return call eliminates undefined behaviour and a later out-of-bounds read causing + * a crash on AMD platforms. + * This behaviour can also affect OpenGL on certain devices. */ discard; return; +#endif } ivec2 texel = ivec2(gl_FragCoord.xy); @@ -235,8 +257,12 @@ void main() float roughness = speccol_roughness.a; if (max_v3(brdf) <= 0.0) { +#if defined(GPU_INTEL) && defined(GPU_METAL) + factor = 0.0f; +#else discard; return; +#endif } FragDepth = depth; @@ -258,5 +284,11 @@ void main() * passed as specular color. */ CLOSURE_EVAL_FUNCTION_1(ssr_resolve, Glossy); + /* Default single pass resolve */ fragColor = vec4(out_Glossy_0.radiance * brdf, 1.0); +#if defined(GPU_INTEL) && defined(GPU_METAL) + /* Due to non-uniform control flow with discard, Intel on macOS requires blending factor + * to discard unwanted fragments. */ + fragColor *= factor; +#endif } diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh index 1afe84be417..3c9169e34c5 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh @@ -227,6 +227,19 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_effect_reflection_resolve) .auto_resource_location(true) .do_static_compilation(true); +/* Split reflection resolve support for Intel-based MacBooks.*/ +GPU_SHADER_CREATE_INFO(eevee_legacy_effect_reflection_resolve_probe) + .define("RESOLVE_PROBE") + .additional_info("eevee_legacy_effect_reflection_resolve") + .auto_resource_location(true) + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(eevee_legacy_effect_reflection_resolve_ssr) + .define("RESOLVE_SSR") + .additional_info("eevee_legacy_effect_reflection_resolve") + .auto_resource_location(true) + .do_static_compilation(true); + /* EEVEE_shaders_subsurface_first_pass_sh_get */ GPU_SHADER_CREATE_INFO(eevee_legacy_shader_effect_subsurface_common) .additional_info("draw_fullscreen") -- 2.30.2