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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user