From ef50249270f8b5c07e5499c0842cad79c9d04069 Mon Sep 17 00:00:00 2001 From: Try Date: Sat, 5 Oct 2024 16:56:11 +0200 Subject: [PATCH] vsm: refactor page-hor-merge in separated shader #681 --- game/graphics/renderer.cpp | 3 + game/graphics/shaders.cpp | 1 + game/graphics/shaders.h | 2 +- shader/CMakeLists.txt | 1 + shader/virtual_shadow/vsm_alloc_pages.comp | 83 ----------------- shader/virtual_shadow/vsm_merge_pages.comp | 101 +++++++++++++++++++++ 6 files changed, 107 insertions(+), 84 deletions(-) create mode 100644 shader/virtual_shadow/vsm_merge_pages.comp diff --git a/game/graphics/renderer.cpp b/game/graphics/renderer.cpp index 5fb6987f9..8a42e3091 100644 --- a/game/graphics/renderer.cpp +++ b/game/graphics/renderer.cpp @@ -894,6 +894,9 @@ void Renderer::drawVsm(Tempest::Encoder& cmd, uint8_t fI // alloc cmd.setUniforms(shaders.vsmAllocPages, vsm.uboAlloc); cmd.dispatch(1); + // hor-merge + cmd.setUniforms(shaders.vsmMergePages, vsm.uboAlloc); + cmd.dispatch(1); cmd.setDebugMarker("VSM-visibility"); wview.visibilityVsm(cmd,fId); diff --git a/game/graphics/shaders.cpp b/game/graphics/shaders.cpp index 73322fb90..d087a9fff 100644 --- a/game/graphics/shaders.cpp +++ b/game/graphics/shaders.cpp @@ -204,6 +204,7 @@ Shaders::Shaders() { vsmTrimPages = computeShader("vsm_trim_pages.comp.sprv"); vsmClumpPages = computeShader("vsm_clump_pages.comp.sprv"); vsmAllocPages = computeShader("vsm_alloc_pages.comp.sprv"); + vsmMergePages = computeShader("vsm_merge_pages.comp.sprv"); vsmPackDraw0 = computeShader("vsm_pack_draws0.comp.sprv"); vsmPackDraw1 = computeShader("vsm_pack_draws1.comp.sprv"); vsmDirectLight = postEffect("copy", "direct_light_vsm", RenderState::ZTestMode::NoEqual); diff --git a/game/graphics/shaders.h b/game/graphics/shaders.h index 8a5e5b2e8..11ea6f07a 100644 --- a/game/graphics/shaders.h +++ b/game/graphics/shaders.h @@ -77,7 +77,7 @@ class Shaders { // Virtual shadow Tempest::ComputePipeline vsmClusterTask; Tempest::ComputePipeline vsmClear, vsmClearPages, vsmMarkPages, vsmMarkSky; - Tempest::ComputePipeline vsmTrimPages, vsmClumpPages, vsmAllocPages; + Tempest::ComputePipeline vsmTrimPages, vsmClumpPages, vsmAllocPages, vsmMergePages; Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1; Tempest::RenderPipeline vsmDirectLight; Tempest::RenderPipeline vsmReprojectSm; diff --git a/shader/CMakeLists.txt b/shader/CMakeLists.txt index 4723878ed..1e881bbe3 100644 --- a/shader/CMakeLists.txt +++ b/shader/CMakeLists.txt @@ -307,6 +307,7 @@ add_shader(vsm_clear_pages.comp virtual_shadow/vsm_clear_pages.comp) add_shader(vsm_trim_pages.comp virtual_shadow/vsm_trim_pages.comp) add_shader(vsm_clump_pages.comp virtual_shadow/vsm_clump_pages.comp) add_shader(vsm_alloc_pages.comp virtual_shadow/vsm_alloc_pages.comp) +add_shader(vsm_merge_pages.comp virtual_shadow/vsm_merge_pages.comp) add_shader(vsm_pack_draws0.comp virtual_shadow/vsm_pack_draws.comp -DPASS0) add_shader(vsm_pack_draws1.comp virtual_shadow/vsm_pack_draws.comp -DPASS1) add_shader(vsm_cluster_task.comp virtual_shadow/vsm_cluster_task.comp -DVIRTUAL_SHADOW) diff --git a/shader/virtual_shadow/vsm_alloc_pages.comp b/shader/virtual_shadow/vsm_alloc_pages.comp index 56a2493b2..8240f9325 100644 --- a/shader/virtual_shadow/vsm_alloc_pages.comp +++ b/shader/virtual_shadow/vsm_alloc_pages.comp @@ -135,87 +135,6 @@ void layoutPages(uint pageData, uint pageSz, uint size) { barrier(); } -void provokingPage(uint lane) { - const uint row = lane/VSM_PAGE_TBL_SIZE; - const uint col = lane%VSM_PAGE_TBL_SIZE; - const uint p = vsm.pageList[lane]; - const uint sz = unpackVsmPageSize(p).x; - const ivec3 at = unpackVsmPageInfo(p); - if(sz<=0) - return; - - if(col==0) { - uint id = atomicAdd(pageListSize, 1); - pageList[id] = lane; - return; - } - - if(col= pageListSize) - return; - - uint pId = pageList[lane]; - const uint row = pId/VSM_PAGE_TBL_SIZE; - const uint col = pId%VSM_PAGE_TBL_SIZE; - const uint p0 = vsm.pageList[pId]; - const uint off = row*VSM_PAGE_TBL_SIZE; - - uint sz = unpackVsmPageSize(p0).x; - ivec3 at = unpackVsmPageInfo(p0); - uint size = sz; - for(uint i=col+sz; i=16) { - // restart stripe - vsm.pageList[pId] = packVsmPageInfo(at, ivec2(size, sz)); - pId = pId1; - sz = sz1; - at = at1; - size = sz1; - continue; - } - vsm.pageList[pId1] = 0; - size += sz; - } - vsm.pageList[pId] = packVsmPageInfo(at, ivec2(size, sz)); - } - void main() { const ivec3 at = ivec3(gl_GlobalInvocationID); const ivec3 id = ivec3(gl_LocalInvocationID); @@ -242,6 +161,4 @@ void main() { layoutPages(frag, size, 4); layoutPages(frag, size, 2); layoutPages(frag, size, 1); - - horizontalMerge(); } diff --git a/shader/virtual_shadow/vsm_merge_pages.comp b/shader/virtual_shadow/vsm_merge_pages.comp new file mode 100644 index 000000000..cac46eb5c --- /dev/null +++ b/shader/virtual_shadow/vsm_merge_pages.comp @@ -0,0 +1,101 @@ +#version 450 + +#extension GL_GOOGLE_include_directive : enable +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_samplerless_texture_functions : enable + +#include "virtual_shadow/vsm_common.glsl" +#include "scene.glsl" +#include "common.glsl" + +layout(local_size_x = 32, local_size_y = 32) in; + +layout(binding = 0, std430) buffer Pages { VsmHeader header; uint pageList[]; } vsm; +layout(binding = 1, r32ui) uniform uimage3D pageTbl; +layout(binding = 2, r32ui) uniform uimage2D dbg; + +const uint NumThreads = gl_WorkGroupSize.x*gl_WorkGroupSize.y*gl_WorkGroupSize.z; + +shared uint pageListSize; +shared uint pageList[VSM_MAX_PAGES]; + +void provokingPage(uint lane) { + const uint row = lane/VSM_PAGE_TBL_SIZE; + const uint col = lane%VSM_PAGE_TBL_SIZE; + const uint p = vsm.pageList[lane]; + const uint sz = unpackVsmPageSize(p).x; + const ivec3 at = unpackVsmPageInfo(p); + if(sz<=0) + return; + + if(col==0) { + uint id = atomicAdd(pageListSize, 1); + pageList[id] = lane; + return; + } + + if(col= pageListSize) + return; + + uint pId = pageList[lane]; + const uint row = pId/VSM_PAGE_TBL_SIZE; + const uint col = pId%VSM_PAGE_TBL_SIZE; + const uint p0 = vsm.pageList[pId]; + const uint off = row*VSM_PAGE_TBL_SIZE; + + uint sz = unpackVsmPageSize(p0).x; + ivec3 at = unpackVsmPageInfo(p0); + uint size = sz; + for(uint i=col+sz; i=16) { + // restart stripe + vsm.pageList[pId] = packVsmPageInfo(at, ivec2(size, sz)); + pId = pId1; + sz = sz1; + at = at1; + size = sz1; + continue; + } + vsm.pageList[pId1] = 0; + size += sz; + } + vsm.pageList[pId] = packVsmPageInfo(at, ivec2(size, sz)); + }