diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.cc b/source/blender/draw/engines/eevee_next/eevee_shadow.cc index 9de56cfbe35..9110632f550 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shadow.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.cc @@ -1287,19 +1287,10 @@ void ShadowModule::set_view(View &view, GPUTexture *depth_tx) int fb_layers = SHADOW_VIEW_MAX; if (shadow_technique == ShadowTechnique::ATOMIC_RASTER) { - if (GPU_backend_get_type() == GPU_BACKEND_METAL) { - /* Metal requires a memoryless attachment to create an empty framebuffer. - * Might as well make use of it. */ - shadow_depth_fb_tx_.ensure_2d_array(GPU_DEPTH_COMPONENT32F, fb_size, fb_layers, usage); - shadow_depth_accum_tx_.free(); - render_fb_.ensure(GPU_ATTACHMENT_TEXTURE(shadow_depth_fb_tx_)); - } - else { - /* Create attachment-less framebuffer. */ - shadow_depth_fb_tx_.free(); - shadow_depth_accum_tx_.free(); - render_fb_.ensure(fb_size); - } + /* Create attachment-less framebuffer. */ + shadow_depth_fb_tx_.free(); + shadow_depth_accum_tx_.free(); + render_fb_.ensure(fb_size); } else if (shadow_technique == ShadowTechnique::TILE_COPY) { /* Create memoryless depth attachment for on-tile surface depth accumulation.*/ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl index 36056795f66..b5a71fd8ae2 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl @@ -152,10 +152,14 @@ void init_interface() #if defined(GPU_VERTEX_SHADER) && defined(MAT_SHADOW) void shadow_viewport_layer_set(int view_id, int lod) { +# ifdef SHADOW_UPDATE_ATOMIC_RASTER + shadow_iface.shadow_view_id = view_id; +# else /* We still render to a layered frame-buffer in the case of Metal + Tile Based Renderer. * Since it needs correct depth buffering, each view needs to not overlap each others. * It doesn't matter much for other platform, so we use that as a way to pass the view id. */ gpu_Layer = view_id; +# endif gpu_ViewportIndex = lod; } #endif @@ -163,6 +167,10 @@ void shadow_viewport_layer_set(int view_id, int lod) #if defined(GPU_FRAGMENT_SHADER) && defined(MAT_SHADOW) int shadow_view_id_get() { +# ifdef SHADOW_UPDATE_ATOMIC_RASTER + return shadow_iface.shadow_view_id; +# else return gpu_Layer; +# endif } #endif diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index dde104254f5..00eb23e19f4 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -226,10 +226,13 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world) // "eevee_cryptomatte_out", "eevee_utility_texture"); +GPU_SHADER_INTERFACE_INFO(eevee_surf_shadow_atomic_iface, "shadow_iface") + .flat(Type::INT, "shadow_view_id"); + GPU_SHADER_CREATE_INFO(eevee_surf_shadow) .define("DRW_VIEW_LEN", STRINGIFY(SHADOW_VIEW_MAX)) .define("MAT_SHADOW") - .builtins(BuiltinBits::VIEWPORT_INDEX | BuiltinBits::LAYER) + .builtins(BuiltinBits::VIEWPORT_INDEX) .storage_buf(SHADOW_VIEWPORT_INDEX_BUF_SLOT, Qualifier::READ, "uint", @@ -244,6 +247,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_shadow_atomic) /* Early fragment test for speeding up platforms that requires a depth buffer. */ /* NOTE: This removes the possibility of using gl_FragDepth. */ .early_fragment_test(true) + .vertex_out(eevee_surf_shadow_atomic_iface) .storage_buf(SHADOW_RENDER_MAP_BUF_SLOT, Qualifier::READ, "uint", @@ -257,6 +261,7 @@ GPU_SHADER_CREATE_INFO(eevee_surf_shadow_atomic) GPU_SHADER_CREATE_INFO(eevee_surf_shadow_tbdr) .additional_info("eevee_surf_shadow") .define("SHADOW_UPDATE_TBDR") + .builtins(BuiltinBits::LAYER) /* F32 color attachment for on-tile depth accumulation without atomics. */ .fragment_out(0, Type::FLOAT, "out_depth", DualBlend::NONE, SHADOW_ROG_ID); diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index c6e8839013b..31cb13f0639 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1084,11 +1084,16 @@ bool MTLContext::ensure_render_pipeline_state(MTLPrimitiveType mtl_prim_type) } else { /* Scissor is disabled, reset to default size as scissor state may have been previously - * assigned on this encoder. */ + * assigned on this encoder. + * NOTE: If an attachment-less framebuffer is used, fetch specified width/height rather + * than active attachment width/height as provided by get_default_w/h().*/ + uint default_w = render_fb->get_default_width(); + uint default_h = render_fb->get_default_height(); + bool is_attachmentless = (default_w == 0) && (default_h == 0); scissor.x = 0; scissor.y = 0; - scissor.width = render_fb->get_default_width(); - scissor.height = render_fb->get_default_height(); + scissor.width = (is_attachmentless) ? render_fb->get_width() : default_w; + scissor.height = (is_attachmentless) ? render_fb->get_height() : default_h; } /* Scissor state can still be flagged as changed if it is toggled on and off, without