From ffcd8e6b026bade0f172700d1736dcd64bb7cc03 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 9 Mar 2023 18:28:05 +0100 Subject: [PATCH] Eevee-next: Use compute shader to clear clipmaps Clearing of clipmaps is the only place in Blender that uses non uniform data (not all components of the cleared data to be exact the same). Vulkan has only the possibility to clear buffers using a single uint32_t. There were two solutions: - Add compute shader to Vulkan backend. - Make Eevee-next responsible to clear the clipmaps. When fixing this in the Vulkan backend it could lead to other issues as the backend isn't aware what is exactly required and might overwrite active bindings. We chose to make it a responsibility of Eevee-next as there it is clear what is needed. Related issue: #105492 Pull Request: https://projects.blender.org/blender/blender/pulls/105560 --- source/blender/draw/CMakeLists.txt | 1 + .../draw/engines/eevee_next/eevee_defines.hh | 1 + .../draw/engines/eevee_next/eevee_shader.cc | 2 ++ .../draw/engines/eevee_next/eevee_shader.hh | 1 + .../draw/engines/eevee_next/eevee_shadow.cc | 22 +++++++++---------- .../eevee_shadow_clipmap_clear_comp.glsl | 13 +++++++++++ .../shaders/infos/eevee_shadow_info.hh | 8 +++++++ 7 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 source/blender/draw/engines/eevee_next/shaders/eevee_shadow_clipmap_clear_comp.glsl diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 311a48cc437..01aa63bb38f 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -467,6 +467,7 @@ set(GLSL_SRC engines/eevee_next/shaders/eevee_sampling_lib.glsl engines/eevee_next/shaders/eevee_shadow_debug_frag.glsl engines/eevee_next/shaders/eevee_shadow_lib.glsl + engines/eevee_next/shaders/eevee_shadow_clipmap_clear_comp.glsl engines/eevee_next/shaders/eevee_shadow_page_allocate_comp.glsl engines/eevee_next/shaders/eevee_shadow_page_clear_comp.glsl engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index 72470ab7060..bc778dc874d 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -54,6 +54,7 @@ #define SHADOW_PAGE_PER_ROW 64 #define SHADOW_ATLAS_SLOT 5 #define SHADOW_BOUNDS_GROUP_SIZE 64 +#define SHADOW_CLIPMAP_GROUP_SIZE 64 #define SHADOW_VIEW_MAX 64 /* Must match DRW_VIEW_MAX. */ /* Ray-tracing. */ diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc index 0207a2574b2..cdf2115c743 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc @@ -142,6 +142,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_ return "eevee_light_culling_tile"; case LIGHT_CULLING_ZBIN: return "eevee_light_culling_zbin"; + case SHADOW_CLIPMAP_CLEAR: + return "eevee_shadow_clipmap_clear"; case SHADOW_DEBUG: return "eevee_shadow_debug"; case SHADOW_PAGE_ALLOCATE: diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.hh b/source/blender/draw/engines/eevee_next/eevee_shader.hh index df689bb2717..d589c55cb50 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader.hh @@ -62,6 +62,7 @@ enum eShaderType { MOTION_BLUR_TILE_FLATTEN_RENDER, MOTION_BLUR_TILE_FLATTEN_VIEWPORT, + SHADOW_CLIPMAP_CLEAR, SHADOW_DEBUG, SHADOW_PAGE_ALLOCATE, SHADOW_PAGE_CLEAR, diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.cc b/source/blender/draw/engines/eevee_next/eevee_shadow.cc index bdaee258e2d..05942d7a131 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shadow.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.cc @@ -835,17 +835,6 @@ void ShadowModule::end_sync() /* Clear tiles to not reference any page. */ tilemap_pool.tiles_data.clear_to_zero(); - /* Clear tile-map clip buffer. */ - union { - ShadowTileMapClip clip; - int4 i; - } u; - u.clip.clip_near_stored = 0.0f; - u.clip.clip_far_stored = 0.0f; - u.clip.clip_near = int(0xFF7FFFFFu ^ 0x7FFFFFFFu); /* floatBitsToOrderedInt(-FLT_MAX) */ - u.clip.clip_far = 0x7F7FFFFF; /* floatBitsToOrderedInt(FLT_MAX) */ - GPU_storagebuf_clear(tilemap_pool.tilemaps_clip, GPU_RGBA32I, GPU_DATA_INT, &u.i); - /* Clear cached page buffer. */ int2 data = {-1, -1}; GPU_storagebuf_clear(pages_cached_data_, GPU_RG32I, GPU_DATA_INT, &data); @@ -867,6 +856,17 @@ void ShadowModule::end_sync() PassSimple &pass = tilemap_setup_ps_; pass.init(); + { + /** Clear tile-map clip buffer. */ + PassSimple::Sub &sub = pass.sub("ClearClipmap"); + sub.shader_set(inst_.shaders.static_shader_get(SHADOW_CLIPMAP_CLEAR)); + sub.bind_ssbo("tilemaps_clip_buf", tilemap_pool.tilemaps_clip); + sub.push_constant("tilemaps_clip_buf_len", int(tilemap_pool.tilemaps_clip.size())); + sub.dispatch(int3( + divide_ceil_u(tilemap_pool.tilemaps_clip.size(), SHADOW_CLIPMAP_GROUP_SIZE), 1, 1)); + sub.barrier(GPU_BARRIER_SHADER_STORAGE); + } + { /** Compute near/far clip distances for directional shadows based on casters bounds. */ PassSimple::Sub &sub = pass.sub("DirectionalBounds"); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_clipmap_clear_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_clipmap_clear_comp.glsl new file mode 100644 index 00000000000..bb807a0a29f --- /dev/null +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_clipmap_clear_comp.glsl @@ -0,0 +1,13 @@ + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) + +void main() +{ + int index = int(gl_GlobalInvocationID.x); + if (index < tilemaps_clip_buf_len) { + tilemaps_clip_buf[index].clip_near_stored = 0; + tilemaps_clip_buf[index].clip_far_stored = 0; + tilemaps_clip_buf[index].clip_near = floatBitsToOrderedInt(-FLT_MAX); + tilemaps_clip_buf[index].clip_far = floatBitsToOrderedInt(FLT_MAX); + } +} \ No newline at end of file diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh index 1da15cf49f5..347928e5061 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_shadow_info.hh @@ -8,6 +8,14 @@ /** \name Shadow pipeline * \{ */ +GPU_SHADER_CREATE_INFO(eevee_shadow_clipmap_clear) + .do_static_compilation(true) + .local_group_size(SHADOW_CLIPMAP_GROUP_SIZE) + .storage_buf(0, Qualifier::WRITE, "ShadowTileMapClip", "tilemaps_clip_buf[]") + .push_constant(Type::INT, "tilemaps_clip_buf_len") + .additional_info("eevee_shared") + .compute_source("eevee_shadow_clipmap_clear_comp.glsl"); + GPU_SHADER_CREATE_INFO(eevee_shadow_tilemap_bounds) .do_static_compilation(true) .local_group_size(SHADOW_BOUNDS_GROUP_SIZE)