From 8583221c2e39a6ac0f4b5d2a09e05f0ddd83135c Mon Sep 17 00:00:00 2001 From: Try Date: Wed, 18 Sep 2024 20:28:16 +0200 Subject: [PATCH] vsm: fragment atomics path #681 --- game/graphics/drawcommands.cpp | 12 +++++- game/graphics/drawcommands.h | 6 ++- game/graphics/renderer.cpp | 35 +++++++++++------ game/graphics/renderer.h | 3 +- game/graphics/sceneglobals.cpp | 2 + game/graphics/sceneglobals.h | 2 + game/graphics/shaders.cpp | 5 +++ game/graphics/shaders.h | 2 +- game/graphics/worldview.cpp | 3 +- game/graphics/worldview.h | 2 +- shader/CMakeLists.txt | 1 + shader/materials/main.frag | 21 +++++++++- shader/materials/main.vert | 43 ++++++++++++++++++++- shader/materials/materials_common.glsl | 13 ++++++- shader/virtual_shadow/vsm_clear.comp | 3 ++ shader/virtual_shadow/vsm_clear_pages.comp | 18 +++++++++ shader/virtual_shadow/vsm_clump_pages.comp | 4 +- shader/virtual_shadow/vsm_cluster_task.comp | 27 +++++++++++++ shader/virtual_shadow/vsm_common.glsl | 11 ++++-- shader/virtual_shadow/vsm_list_pages.comp | 5 +++ shader/virtual_shadow/vsm_mark_pages.comp | 11 +++++- 21 files changed, 197 insertions(+), 32 deletions(-) create mode 100644 shader/virtual_shadow/vsm_clear_pages.comp diff --git a/game/graphics/drawcommands.cpp b/game/graphics/drawcommands.cpp index 9c92ad2b3..741aff7ff 100644 --- a/game/graphics/drawcommands.cpp +++ b/game/graphics/drawcommands.cpp @@ -336,7 +336,15 @@ void DrawCommands::updateCommandUniforms() { desc[v].set(L_GDepth, *scene.sceneDepth, smp); } - if(v==SceneGlobals::V_Vsm) { + if(v==SceneGlobals::V_Vsm && scene.vsmPageData!=nullptr && !scene.vsmPageData->isEmpty()) { + // atomic + desc[v].set(L_CmdOffsets, views[v].indirectCmd); + desc[v].set(L_VsmPages, *scene.vsmPageList); + desc[v].set(L_VsmTbl, *scene.vsmPageTbl); + desc[v].set(L_VsmData, *scene.vsmPageData); + } + if(v==SceneGlobals::V_Vsm && scene.vsmPageData!=nullptr && scene.vsmPageData->isEmpty()) { + // raster desc[v].set(L_CmdOffsets, views[v].indirectCmd); desc[v].set(L_VsmPages, *scene.vsmPageList); } @@ -398,7 +406,7 @@ void DrawCommands::updateVsmUniforms() { Resources::recycle(std::move(vsmDesc)); vsmDesc = device.descriptors(Shaders::inst().vsmRendering); - vsmDesc.set(0, vsmSwrImage); + vsmDesc.set(0, *scene.vsmPageData); vsmDesc.set(1, scene.uboGlobal[SceneGlobals::V_Vsm]); vsmDesc.set(2, *scene.vsmPageList); vsmDesc.set(3, clusters.ssbo()); diff --git a/game/graphics/drawcommands.h b/game/graphics/drawcommands.h index f7902e5e5..f4bcaeb69 100644 --- a/game/graphics/drawcommands.h +++ b/game/graphics/drawcommands.h @@ -102,7 +102,9 @@ class DrawCommands { L_SceneClr = 12, L_GDepth = 13, L_CmdOffsets = 14, - L_VsmPages = 15, + L_VsmPages = L_Shadow0, + L_VsmTbl = L_Shadow1, + L_VsmData = 15, }; struct IndirectCmd { @@ -147,6 +149,6 @@ class DrawCommands { View views[SceneGlobals::V_Count]; Tempest::StorageBuffer vsmIndirectCmd; - Tempest::StorageImage vsmSwrImage; + // Tempest::StorageImage vsmSwrImage; Tempest::DescriptorSet vsmDesc; }; diff --git a/game/graphics/renderer.cpp b/game/graphics/renderer.cpp index c91eefe5f..a6fcc57a8 100644 --- a/game/graphics/renderer.cpp +++ b/game/graphics/renderer.cpp @@ -190,6 +190,8 @@ void Renderer::resetSwapchain() { if(settings.vsmEnabled) { vsm.pagesClearPso = &Shaders::inst().vsmClear; vsm.uboClear = device.descriptors(*vsm.pagesClearPso); + if(!vsm.pageDataCs.isEmpty()) + vsm.uboClearPages = device.descriptors(Shaders::inst().vsmClearPages); vsm.pagesMarkPso = &Shaders::inst().vsmMarkPages; vsm.uboPages = device.descriptors(*vsm.pagesMarkPso); @@ -204,12 +206,12 @@ void Renderer::resetSwapchain() { vsm.uboDbg = device.descriptors(*vsm.pagesDbgPso); vsm.pageTbl = device.image3d(TextureFormat::R32U, 32, 32, 16); + // vsm.pageDataCs = device.image2d(TextureFormat::R32U, 4096, 4096); vsm.pageData = device.zbuffer(shadowFormat, 4096, 4096); - vsm.shadowMask = device.image2d(Tempest::RGBA8, w, h); const int32_t VSM_PAGE_SIZE = 128; auto pageCount = uint32_t((vsm.pageData.w()+VSM_PAGE_SIZE-1)/VSM_PAGE_SIZE) * uint32_t((vsm.pageData.h()+VSM_PAGE_SIZE-1)/VSM_PAGE_SIZE); - vsm.pageList = device.ssbo(nullptr, (pageCount + 4)*sizeof(uint32_t)); + vsm.pageList = device.ssbo(nullptr, (pageCount + 4 + 16*4)*sizeof(uint32_t)); } if(settings.swrEnabled) { @@ -452,6 +454,9 @@ void Renderer::prepareUniforms() { vsm.uboClear.set(0, vsm.pageList); vsm.uboClear.set(1, vsm.pageTbl); + if(!vsm.uboClearPages.isEmpty()) + vsm.uboClearPages.set(0, vsm.pageDataCs); + vsm.uboPages.set(0, wview->sceneGlobals().uboGlobal[SceneGlobals::V_Main]); vsm.uboPages.set(1, gbufDiffuse, Sampler::nearest()); vsm.uboPages.set(2, gbufNormal, Sampler::nearest()); @@ -466,8 +471,9 @@ void Renderer::prepareUniforms() { vsm.uboLight.set(2, gbufNormal, Sampler::nearest()); vsm.uboLight.set(3, zbuffer, Sampler::nearest()); vsm.uboLight.set(4, vsm.pageTbl); - vsm.uboLight.set(5, vsm.pageData); - vsm.uboLight.set(6, vsm.shadowMask); + if(!vsm.pageDataCs.isEmpty()) + vsm.uboLight.set(5, vsm.pageDataCs); else + vsm.uboLight.set(5, vsm.pageData); vsm.uboDbg.set(0, wview->sceneGlobals().uboGlobal[SceneGlobals::V_Main]); vsm.uboDbg.set(1, gbufDiffuse, Sampler::nearest()); @@ -475,7 +481,6 @@ void Renderer::prepareUniforms() { vsm.uboDbg.set(3, zbuffer, Sampler::nearest()); vsm.uboDbg.set(4, vsm.pageTbl); vsm.uboDbg.set(5, vsm.pageData); - vsm.uboDbg.set(6, vsm.shadowMask); } if(settings.swrEnabled) { @@ -492,7 +497,7 @@ void Renderer::prepareUniforms() { sh[i] = &textureCast(shadowMap[i]); } wview->setShadowMaps(sh); - wview->setVirtualShadowMap(StorageImage(), vsm.pageList); + wview->setVirtualShadowMap(vsm.pageDataCs, vsm.pageTbl, vsm.pageList); wview->setSwRenderingImage(swr.outputImage); wview->setHiZ(textureCast(hiz.hiZ)); @@ -859,12 +864,20 @@ void Renderer::drawVsm(Tempest::Encoder& cmd, uint8_t fI cmd.setUniforms(*vsm.pagesMarkPso, vsm.uboPages); cmd.dispatchThreads(zbuffer.size()); - //TODO: trimming - //cmd.setUniforms(Shaders::inst().vsmClumpPages0, vsm.uboList); - //cmd.dispatch(1); + if(vsm.pageDataCs.isEmpty()) { + //TODO: trimming + //cmd.setUniforms(Shaders::inst().vsmClumpPages0, vsm.uboList); + //cmd.dispatch(1); - cmd.setUniforms(Shaders::inst().vsmClumpPages1, vsm.uboList); - cmd.dispatchThreads(size_t(vsm.pageTbl.w()), size_t(vsm.pageTbl.h()), size_t(vsm.pageTbl.d())); + // clump + cmd.setUniforms(Shaders::inst().vsmClumpPages1, vsm.uboList); + cmd.dispatchThreads(size_t(vsm.pageTbl.w()), size_t(vsm.pageTbl.h()), size_t(vsm.pageTbl.d())); + } + + if(!vsm.pageDataCs.isEmpty()) { + cmd.setUniforms(Shaders::inst().vsmClearPages, vsm.uboClearPages); + cmd.dispatchThreads(size_t(vsm.pageDataCs.w()), size_t(vsm.pageDataCs.h())); + } cmd.setUniforms(*vsm.pagesListPso, vsm.uboList); cmd.dispatchThreads(size_t(vsm.pageTbl.w()), size_t(vsm.pageTbl.h()), size_t(vsm.pageTbl.d())); diff --git a/game/graphics/renderer.h b/game/graphics/renderer.h index 32429cd8a..1e513319d 100644 --- a/game/graphics/renderer.h +++ b/game/graphics/renderer.h @@ -213,6 +213,7 @@ class Renderer final { struct { Tempest::ComputePipeline* pagesClearPso = nullptr; Tempest::DescriptorSet uboClear; + Tempest::DescriptorSet uboClearPages; Tempest::ComputePipeline* pagesMarkPso = nullptr; Tempest::DescriptorSet uboPages; @@ -227,9 +228,9 @@ class Renderer final { Tempest::DescriptorSet uboDbg; Tempest::StorageImage pageTbl; + Tempest::StorageImage pageDataCs; Tempest::ZBuffer pageData; Tempest::StorageBuffer pageList; - Tempest::StorageImage shadowMask; } vsm; struct { diff --git a/game/graphics/sceneglobals.cpp b/game/graphics/sceneglobals.cpp index 7c537e5f1..94cd6cc44 100644 --- a/game/graphics/sceneglobals.cpp +++ b/game/graphics/sceneglobals.cpp @@ -212,8 +212,10 @@ void SceneGlobals::setShadowMap(const Tempest::Texture2d* tex[]) { } void SceneGlobals::setVirtualShadowMap(const Tempest::StorageImage& pageData, + const Tempest::StorageImage& pageTbl, const Tempest::StorageBuffer& pageList) { vsmPageData = &pageData; + vsmPageTbl = &pageTbl; vsmPageList = &pageList; } diff --git a/game/graphics/sceneglobals.h b/game/graphics/sceneglobals.h index 7f3beb0c0..5439c746c 100644 --- a/game/graphics/sceneglobals.h +++ b/game/graphics/sceneglobals.h @@ -43,6 +43,7 @@ class SceneGlobals final { void setShadowMap(const Tempest::Texture2d* tex[]); void setVirtualShadowMap(const Tempest::StorageImage& vsmPageData, + const Tempest::StorageImage& pageTbl, const Tempest::StorageBuffer& vsmPageList); void setSwRenderingImage(const Tempest::StorageImage& mainView); @@ -75,6 +76,7 @@ class SceneGlobals final { const Tempest::StorageBuffer* lights = nullptr; const Tempest::StorageImage* vsmPageData = nullptr; + const Tempest::StorageImage* vsmPageTbl = nullptr; const Tempest::StorageBuffer* vsmPageList = nullptr; const Tempest::StorageImage* swMainImage = nullptr; diff --git a/game/graphics/shaders.cpp b/game/graphics/shaders.cpp index 580d3870c..39f92fbf1 100644 --- a/game/graphics/shaders.cpp +++ b/game/graphics/shaders.cpp @@ -197,6 +197,7 @@ Shaders::Shaders() { if(Gothic::options().doVirtualShadow) { vsmClusterTask = computeShader("vsm_cluster_task.comp.sprv"); vsmClear = computeShader("vsm_clear.comp.sprv"); + vsmClearPages = computeShader("vsm_clear_pages.comp.sprv"); vsmMarkPages = computeShader("vsm_mark_pages.comp.sprv"); vsmClumpPages0 = computeShader("vsm_clump_pages0.comp.sprv"); vsmClumpPages1 = computeShader("vsm_clump_pages1.comp.sprv"); @@ -274,6 +275,10 @@ const RenderPipeline* Shaders::materialPipeline(const Material& mat, DrawCommand if(pt==PipelineType::T_Shadow || pt==PipelineType::T_Vsm) { state.setZTestMode(RenderState::ZTestMode::Greater); //FIXME } + if(pt==PipelineType::T_Vsm) { + // state.setZTestMode(RenderState::ZTestMode::Always); //FIXME + state.setZTestMode(RenderState::ZTestMode::Greater); //FIXME + } switch(alpha) { case Material::Solid: diff --git a/game/graphics/shaders.h b/game/graphics/shaders.h index b5df2a8b2..811ee3e18 100644 --- a/game/graphics/shaders.h +++ b/game/graphics/shaders.h @@ -76,7 +76,7 @@ class Shaders { // Virtual shadow Tempest::ComputePipeline vsmClusterTask; - Tempest::ComputePipeline vsmClear, vsmMarkPages, vsmListPages; + Tempest::ComputePipeline vsmClear, vsmClearPages, vsmMarkPages, vsmListPages; Tempest::ComputePipeline vsmClumpPages0, vsmClumpPages1; Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1; Tempest::RenderPipeline vsmDirectLight; diff --git a/game/graphics/worldview.cpp b/game/graphics/worldview.cpp index d70bebe45..03c4b07d3 100644 --- a/game/graphics/worldview.cpp +++ b/game/graphics/worldview.cpp @@ -86,8 +86,9 @@ void WorldView::setShadowMaps(const Tempest::Texture2d* sh[]) { } void WorldView::setVirtualShadowMap(const Tempest::StorageImage& pageData, + const Tempest::StorageImage& pageTbl, const Tempest::StorageBuffer& pageList) { - sGlobal.setVirtualShadowMap(pageData, pageList); + sGlobal.setVirtualShadowMap(pageData, pageTbl, pageList); } void WorldView::setSwRenderingImage(const Tempest::StorageImage& mainView) { diff --git a/game/graphics/worldview.h b/game/graphics/worldview.h index 47567f9dc..d04dcc42e 100644 --- a/game/graphics/worldview.h +++ b/game/graphics/worldview.h @@ -37,7 +37,7 @@ class WorldView { void setGbuffer(const Tempest::Texture2d& diffuse, const Tempest::Texture2d& norm); void setShadowMaps (const Tempest::Texture2d* shadow[]); - void setVirtualShadowMap(const Tempest::StorageImage& pageData, const Tempest::StorageBuffer& pageList); + void setVirtualShadowMap(const Tempest::StorageImage& pageData, const Tempest::StorageImage& pageTbl, const Tempest::StorageBuffer& pageList); void setSwRenderingImage(const Tempest::StorageImage& mainView); void setHiZ(const Tempest::Texture2d& hiZ); void setSceneImages(const Tempest::Texture2d& clr, const Tempest::Texture2d& depthAux, const Tempest::ZBuffer& depthNative); diff --git a/shader/CMakeLists.txt b/shader/CMakeLists.txt index 9b08d6d83..013548c75 100644 --- a/shader/CMakeLists.txt +++ b/shader/CMakeLists.txt @@ -302,6 +302,7 @@ add_shader(direct_light_vsm.frag virtual_shadow/vsm_mark_pages.comp -DCOMPOSE add_shader(vsm_dbg.frag virtual_shadow/vsm_mark_pages.comp -DDEBUG -DLWC -S frag) add_shader(vsm_mark_pages.comp virtual_shadow/vsm_mark_pages.comp -DMARK_PAGES -DLWC) add_shader(vsm_clear.comp virtual_shadow/vsm_clear.comp) +add_shader(vsm_clear_pages.comp virtual_shadow/vsm_clear_pages.comp) add_shader(vsm_clump_pages0.comp virtual_shadow/vsm_clump_pages.comp -DPASS0) add_shader(vsm_clump_pages1.comp virtual_shadow/vsm_clump_pages.comp -DPASS1) add_shader(vsm_list_pages.comp virtual_shadow/vsm_list_pages.comp) diff --git a/shader/materials/main.frag b/shader/materials/main.frag index b8c7148ca..a6e2bcfdd 100644 --- a/shader/materials/main.frag +++ b/shader/materials/main.frag @@ -17,6 +17,10 @@ layout(location = 0) in flat uint bucketId; layout(location = 1) in Varyings shInp; #endif +#if defined(VIRTUAL_SHADOW) +layout(location = 3) in flat uint vsmMipId; +#endif + #if DEBUG_DRAW layout(location = DEBUG_DRAW_LOC) in flat uint debugId; #endif @@ -307,6 +311,19 @@ void mainWater(vec4 t) { } #endif +#if defined(VIRTUAL_SHADOW) && defined(VSM_ATOMIC) +bool vsmPageTest() { + ivec2 pc = ivec2(gl_FragCoord.xy)/VSM_PAGE_SIZE; + uint pageId = imageLoad(pageTbl, ivec3(pc, vsmMipId)).r; + if(pageId==0xFFFFFFFF) + return false; + ivec2 frac = ivec2(gl_FragCoord.xy)%VSM_PAGE_SIZE; + ivec2 at = unpackVsmPageId(pageId) * VSM_PAGE_SIZE + frac; + imageAtomicMax(vsmData, at, floatBitsToUint(gl_FragCoord.z)); + return true; + } +#endif + void main() { #if defined(MAT_UV) vec4 t = diffuseTex(); @@ -316,10 +333,12 @@ void main() { # endif #endif -#if defined(VIRTUAL_SHADOW) +#if defined(VIRTUAL_SHADOW) && defined(VSM_ATOMIC) // NOTE: use clip-distance is used instead // if(!vsmPageClip(ivec2(gl_FragCoord.xy), vsmPageId)) // discard; + if(!vsmPageTest()) + discard; #endif #if defined(MAT_COLOR) diff --git a/shader/materials/main.vert b/shader/materials/main.vert index d1a4db514..6dbdf4fd8 100644 --- a/shader/materials/main.vert +++ b/shader/materials/main.vert @@ -52,11 +52,20 @@ layout(location = 0) out flat uint bucketIdOut[]; //TODO: per-primitive layout(location = 1) out Varyings shOut[]; #endif -#if defined(VIRTUAL_SHADOW) +#if defined(GL_VERTEX_SHADER) && defined(VIRTUAL_SHADOW) +layout(location = 3) out flat uint vsmMipIdOut; +#elif defined(VIRTUAL_SHADOW) +layout(location = 3) out flat uint vsmMipIdOut[]; +#endif + +#if defined(VIRTUAL_SHADOW) && !defined(VSM_ATOMIC) uint shadowPageId = 0; #endif +#if defined(VIRTUAL_SHADOW) && defined(VSM_ATOMIC) +uint shadowMip = 0; +#endif -#if defined(VIRTUAL_SHADOW) +#if defined(VIRTUAL_SHADOW) && !defined(VSM_ATOMIC) vec4 mapViewport(vec4 pos, out float clipDistance[4]) { const uint data = vsm.pageList[shadowPageId]; const ivec3 page = unpackVsmPageInfo(data); @@ -81,9 +90,37 @@ vec4 mapViewport(vec4 pos, out float clipDistance[4]) { } #endif +#if defined(VIRTUAL_SHADOW) && defined(VSM_ATOMIC) +vec4 mapViewport(vec4 pos, out float clipDistance[4]) { + pos.xy /= float(1u << shadowMip); + + ivec4 hdr = vsm.header.pageBbox[shadowMip]; + ivec2 sz = hdr.zw - hdr.xy; + + vec2 clip = (pos.xy*0.5+0.5); // [0..1] + clip = clip.xy*VSM_PAGE_TBL_SIZE - ivec2(hdr.xy); + { + clipDistance[0] = 0 + clip.x; + clipDistance[1] = sz.x - clip.x; + clipDistance[2] = 0 + clip.y; + clipDistance[3] = sz.y - clip.y; + } + return pos; + } +#endif + #if defined(VIRTUAL_SHADOW) void initVsm(uvec4 task) { +#if !defined(VSM_ATOMIC) shadowPageId = task.w & 0xFFFF; +#else + shadowMip = task.w & 0xFF; +# if defined(GL_VERTEX_SHADER) + vsmMipIdOut = shadowMip; +# else + vsmMipIdOut[gl_LocalInvocationIndex] = shadowMip; +# endif +#endif } #endif @@ -164,6 +201,7 @@ void vertexShader(const uvec4 task) { vec4 pos = processVertex(var, instanceId, meshletId, bucketId, idx); #if defined(VIRTUAL_SHADOW) pos = mapViewport(pos, gl_ClipDistance); + // pos = mapViewport(pos); #endif gl_Position = pos; #if defined(MAT_VARYINGS) @@ -196,6 +234,7 @@ void meshShader(const uvec4 task) { vec4 pos = processVertex(var, instanceId, meshletId, bucketId, laneID); #if defined(VIRTUAL_SHADOW) pos = mapViewport(pos, gl_MeshVerticesEXT[laneID].gl_ClipDistance); + // pos = mapViewport(pos); #endif gl_MeshVerticesEXT[laneID].gl_Position = pos; diff --git a/shader/materials/materials_common.glsl b/shader/materials/materials_common.glsl index ec605dfd3..a7cea3979 100644 --- a/shader/materials/materials_common.glsl +++ b/shader/materials/materials_common.glsl @@ -60,7 +60,9 @@ const uint L_Morph = 11; const uint L_SceneClr = 12; const uint L_GDepth = 13; const uint L_CmdOffsets = 14; -const uint L_VsmPages = 15; +const uint L_VsmPages = L_Shadow0; +const uint L_VsmTbl = L_Shadow1; +const uint L_VsmData = 15; #define T_LANDSCAPE 0 #define T_OBJ 1 @@ -204,7 +206,14 @@ layout(binding = L_SceneClr) uniform sampler2D sceneColor; layout(binding = L_GDepth ) uniform sampler2D gbufferDepth; #endif -#if defined(VIRTUAL_SHADOW) && !defined(CLUSTER) +#if defined(VIRTUAL_SHADOW) && defined(VSM_ATOMIC) && !defined(CLUSTER) +layout(binding = L_CmdOffsets, std430) readonly buffer IndirectBuf { IndirectCmd cmd[]; }; +layout(binding = L_VsmPages, std430) readonly buffer Pages { VsmHeader header; uint pageList[]; } vsm; +layout(binding = L_VsmTbl, r32ui) uniform readonly uimage3D pageTbl; +layout(binding = L_VsmData, r32ui) uniform uimage2D vsmData; +#endif + +#if defined(VIRTUAL_SHADOW) && !defined(VSM_ATOMIC) && !defined(CLUSTER) layout(binding = L_CmdOffsets, std430) readonly buffer IndirectBuf { IndirectCmd cmd[]; }; layout(binding = L_VsmPages, std430) readonly buffer Pages { VsmHeader header; uint pageList[]; } vsm; #endif diff --git a/shader/virtual_shadow/vsm_clear.comp b/shader/virtual_shadow/vsm_clear.comp index fc8fdc9d4..099981cd9 100644 --- a/shader/virtual_shadow/vsm_clear.comp +++ b/shader/virtual_shadow/vsm_clear.comp @@ -28,4 +28,7 @@ void main() { header.counterM = 0; header.counterV = 0; } + + if(gl_LocalInvocationIndex<16) + header.pageBbox[gl_LocalInvocationIndex] = ivec4(0xFF, 0xFF, 0, 0); } diff --git a/shader/virtual_shadow/vsm_clear_pages.comp b/shader/virtual_shadow/vsm_clear_pages.comp new file mode 100644 index 000000000..1969bdeba --- /dev/null +++ b/shader/virtual_shadow/vsm_clear_pages.comp @@ -0,0 +1,18 @@ +#version 450 + +#extension GL_GOOGLE_include_directive : enable +#extension GL_ARB_separate_shader_objects : enable +#extension GL_EXT_samplerless_texture_functions : enable + +layout(local_size_x = 8, local_size_y = 8) in; + +layout(binding = 0, r32ui) uniform uimage2D vsmData; + +void main() { + const ivec2 at = ivec2(gl_GlobalInvocationID.xy); + const ivec2 size = imageSize(vsmData); + if(any(greaterThanEqual(at, size))) + return; + + imageStore(vsmData, at, uvec4(0)); + } diff --git a/shader/virtual_shadow/vsm_clump_pages.comp b/shader/virtual_shadow/vsm_clump_pages.comp index 480423914..c9f025b50 100644 --- a/shader/virtual_shadow/vsm_clump_pages.comp +++ b/shader/virtual_shadow/vsm_clump_pages.comp @@ -72,12 +72,12 @@ void mainGroups() { groupMemoryBarrier(); barrier(); - if(true && at.x%4==0 && at.y%4==0) { + if(false && at.x%4==0 && at.y%4==0) { uint a = imageLoad(pageTbl, at+ivec3(0,0,0)).r; uint b = imageLoad(pageTbl, at+ivec3(2,0,0)).r; uint c = imageLoad(pageTbl, at+ivec3(2,2,0)).r; uint d = imageLoad(pageTbl, at+ivec3(0,2,0)).r; - if(a+b+c+d >= 3) { + if(a+b+c+d >= 4) { imageStore(pageTbl, at+ivec3(0,0,0), uvec4(4)); imageStore(pageTbl, at+ivec3(2,0,0), uvec4(0)); imageStore(pageTbl, at+ivec3(0,2,0), uvec4(0)); diff --git a/shader/virtual_shadow/vsm_cluster_task.comp b/shader/virtual_shadow/vsm_cluster_task.comp index cc2b2c7fd..c5ebb73fe 100644 --- a/shader/virtual_shadow/vsm_cluster_task.comp +++ b/shader/virtual_shadow/vsm_cluster_task.comp @@ -115,6 +115,10 @@ bool pageBoundsTest(in vec4 aabb, const ivec3 page, const ivec2 sz) { return true; } +#if defined(VSM_ATOMIC) +shared uint mipMask; +#endif + void runCluster(const uint clusterId) { const Cluster cluster = clusters[clusterId]; if(cluster.sphere.w<=0.f) @@ -136,6 +140,7 @@ void runCluster(const uint clusterId) { const uint pageCount = vsm.header.pageCount; bool anyPage = false; + uint localMipMask = 0; for(uint i=gl_LocalInvocationIndex; i 1000000) + ;//return; + for(int i=0; i