Skip to content

Commit

Permalink
vsm: refactor page-hor-merge in separated shader
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Oct 5, 2024
1 parent 65315a2 commit ef50249
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 84 deletions.
3 changes: 3 additions & 0 deletions game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,9 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& 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);
Expand Down
1 change: 1 addition & 0 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
83 changes: 0 additions & 83 deletions shader/virtual_shadow/vsm_alloc_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -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<sz.x)
return;
//return;

const uint p1 = vsm.pageList[lane-sz.x];
const uint sz1 = unpackVsmPageSize(p1).x;
const ivec3 at1 = unpackVsmPageInfo(p1);

if(sz==sz1 && at1+ivec3(sz,0,0)==at)
return;

uint id = atomicAdd(pageListSize, 1);
pageList[id] = lane;
}

void horizontalMerge() {
const uint lane = gl_LocalInvocationIndex;
pageListSize = 0;

memoryBarrierBuffer();
barrier();

// provoking pages
if(lane < vsm.header.pageCount)
provokingPage(lane);
barrier();

if(lane < pageListSize) {
//uint id = pageList[lane];
//vsm.pageList[id] = 0;
}

if(lane >= 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<VSM_PAGE_TBL_SIZE; i+=sz) {
const uint pId1 = off+i;
const uint p1 = vsm.pageList[pId1];
const uint sz1 = unpackVsmPageSize(p1).x;
const ivec3 at1 = unpackVsmPageInfo(p1);
if(sz!=sz1 || at+uvec3(size,0,0)!=at1)
break;
if(size+sz>=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);
Expand All @@ -242,6 +161,4 @@ void main() {
layoutPages(frag, size, 4);
layoutPages(frag, size, 2);
layoutPages(frag, size, 1);

horizontalMerge();
}
101 changes: 101 additions & 0 deletions shader/virtual_shadow/vsm_merge_pages.comp
Original file line number Diff line number Diff line change
@@ -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<sz.x)
return;
//return;

const uint p1 = vsm.pageList[lane-sz.x];
const uint sz1 = unpackVsmPageSize(p1).x;
const ivec3 at1 = unpackVsmPageInfo(p1);

if(sz==sz1 && at1+ivec3(sz,0,0)==at)
return;

uint id = atomicAdd(pageListSize, 1);
pageList[id] = lane;
}

void main() {
const uint lane = gl_LocalInvocationIndex;

pageListSize = 0;
barrier();

// provoking pages
if(lane < vsm.header.pageCount)
provokingPage(lane);
barrier();

//vsm.header.counterM = pageListSize;
if(lane < pageListSize) {
//uint id = pageList[lane];
//vsm.pageList[id] = 0;
}

if(lane >= 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<VSM_PAGE_TBL_SIZE; i+=sz) {
const uint pId1 = off+i;
const uint p1 = vsm.pageList[pId1];
const uint sz1 = unpackVsmPageSize(p1).x;
const ivec3 at1 = unpackVsmPageInfo(p1);
if(sz!=sz1 || at+uvec3(size,0,0)!=at1)
break;
if(size+sz>=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));
}

0 comments on commit ef50249

Please sign in to comment.