Skip to content

Commit

Permalink
split page listing and page alocation
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Oct 10, 2024
1 parent 0db60b0 commit 05074bf
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 53 deletions.
6 changes: 5 additions & 1 deletion game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void Renderer::resetSwapchain() {

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 + 16*4)*sizeof(uint32_t));
vsm.pageList = device.ssbo(nullptr, (pageCount + 4 + 16*4 + 16*4)*sizeof(uint32_t));
}

if(settings.swrEnabled) {
Expand Down Expand Up @@ -890,6 +890,10 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fI
cmd.dispatchThreads(size_t(vsm.pageDataCs.w()), size_t(vsm.pageDataCs.h()));
}

// list?
cmd.setUniforms(shaders.vsmListPages, vsm.uboAlloc);
cmd.dispatch(size_t(vsm.pageTbl.d()));

// alloc
cmd.setUniforms(shaders.vsmAllocPages, vsm.uboAlloc);
cmd.dispatch(1);
Expand Down
1 change: 1 addition & 0 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ Shaders::Shaders() {
vsmMarkSky = computeShader("fog3d_vsm_mark_pages.comp.sprv");
vsmTrimPages = computeShader("vsm_trim_pages.comp.sprv");
vsmClumpPages = computeShader("vsm_clump_pages.comp.sprv");
vsmListPages = computeShader("vsm_list_pages.comp.sprv");
vsmAllocPages = computeShader("vsm_alloc_pages.comp.sprv");
vsmMergePages = computeShader("vsm_merge_pages.comp.sprv");
vsmPackDraw0 = computeShader("vsm_pack_draws0.comp.sprv");
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, vsmMergePages;
Tempest::ComputePipeline vsmTrimPages, vsmListPages, vsmClumpPages, vsmAllocPages, vsmMergePages;
Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1;
Tempest::RenderPipeline vsmDirectLight;
Tempest::RenderPipeline vsmReprojectSm;
Expand Down
2 changes: 1 addition & 1 deletion shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,12 @@ 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_trim_pages.comp virtual_shadow/vsm_trim_pages.comp)
add_shader(vsm_clump_pages.comp virtual_shadow/vsm_clump_pages.comp)
add_shader(vsm_list_pages.comp virtual_shadow/vsm_list_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)
#add_shader(vsm_list_pages.comp virtual_shadow/vsm_list_pages.comp)

add_shader(vsm_rendering.comp virtual_shadow/vsm_rendering.comp)

Expand Down
44 changes: 10 additions & 34 deletions shader/virtual_shadow/vsm_alloc_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ shared uint bits[(NumThreads+31)/32];
shared uint ladder [VSM_PAGE_TBL_SIZE];
shared uint ladderWr[VSM_PAGE_TBL_SIZE];

ivec2 loadPageSize(ivec3 at) {
uint a = imageLoad(pageTbl, at).r;
a = a >> 1;
return ivec2(a, a >> 4) & 0xF;
}

void storePage(ivec2 pId, ivec3 at, ivec2 tile, ivec2 size) {
const uint pageId = pId.x + pId.y*VSM_PAGE_PER_ROW;

Expand All @@ -55,31 +49,12 @@ uint bitCountShared(uint till) {
}

void listPages() {
const ivec3 size = imageSize(pageTbl);
const uint lane = gl_LocalInvocationIndex;
const ivec3 at = ivec3(gl_GlobalInvocationID);
pageListSize = 0;
const uint lane = gl_LocalInvocationIndex;

for(int i=0; i<1111 && i<size.z; ++i) {
const ivec2 sz = loadPageSize(ivec3(at.xy, i));
if(lane < bits.length())
bits[lane] = 0;
barrier();

if(sz.x>0)
atomicOr(bits[lane/32], 1u<<(lane%32));
barrier();

if(sz.x>0) {
uint id = pageListSize + bitCountShared(lane);
pageList[id] = packVsmPageInfo(ivec3(at.xy, i), sz);
}
barrier();

if(sz.x>0)
atomicAdd(pageListSize, 1);
barrier();
}
pageListSize = vsm.header.pageCount;
for(uint i=lane; i<pageListSize; i+=NumThreads)
pageList[i] = vsm.pageList[i];
barrier();
}

ivec2 findRowCol(in uint page, const uvec2 size) {
Expand Down Expand Up @@ -141,20 +116,21 @@ void main() {
const ivec3 at = ivec3(gl_GlobalInvocationID);
const ivec3 id = ivec3(gl_LocalInvocationID);
const uint lane = gl_LocalInvocationIndex;
if(lane < ladderWr.length())
ladderWr[lane] = 0;
barrier();

imageStore(dbg, at.xy, uvec4(0));
memoryBarrierImage();
barrier();

if(lane < ladderWr.length())
ladderWr[lane] = 0;
listPages();

if(lane < vsm.pageList.length())
vsm.pageList[lane] = 0;
memoryBarrierBuffer();
barrier();

listPages();

const uint frag = lane<pageListSize ? pageList[lane] : 0;
const uvec2 size = unpackVsmPageSize(frag);
barrier();
Expand Down
6 changes: 4 additions & 2 deletions shader/virtual_shadow/vsm_clear.comp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void main() {
header.counterV = 0;
}

if(gl_LocalInvocationIndex<16)
header.pageBbox[gl_LocalInvocationIndex] = ivec4(0xFF, 0xFF, 0, 0);
if(gl_LocalInvocationIndex<16) {
header.pagePerMip[gl_LocalInvocationIndex] = 0;
header.pageBbox [gl_LocalInvocationIndex] = ivec4(0xFF, 0xFF, 0, 0);
}
}
2 changes: 2 additions & 0 deletions shader/virtual_shadow/vsm_clump_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ void storePageTable() {
uint p = unpackPrimeBit(d);
uvec2 s = uvec2(unpackSize(d));
imageStore(pageTbl, at, uvec4(p | (s.x << 1) | (s.y << 5)));
if(s.x>0)
atomicAdd(vsm.header.pagePerMip[at.z], 1);
}
}

Expand Down
1 change: 1 addition & 0 deletions shader/virtual_shadow/vsm_common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ struct VsmHeader {
uint meshletCount;
uint counterM;
uint counterV;
uint pagePerMip[VSM_PAGE_MIPS];
ivec4 pageBbox[VSM_PAGE_MIPS];
};

Expand Down
72 changes: 58 additions & 14 deletions shader/virtual_shadow/vsm_list_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,71 @@
#include "scene.glsl"
#include "common.glsl"

//layout(local_size_x = 64) in;
layout(local_size_x = 8, local_size_y = 8) in;
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 readonly uimage3D pageTblDepth;
//layout(binding = 1, std430) writeonly buffer Dst { VsmHeader header; uint pageList[]; } dst;
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;

void main() {
const ivec3 at = ivec3(gl_GlobalInvocationID.xyz);
shared uint pageListPrefix;
shared uint bits[(NumThreads+31)/32];

ivec2 loadPageSize(ivec3 at) {
uint a = imageLoad(pageTbl, at).r;
a = a >> 1;
return ivec2(a, a >> 4) & 0xF;
}

uint bitCountShared(uint till) {
uint n = till/32;
uint f = till%32;
uint r = 0;
for(uint i=0; i<n; ++i)
r += bitCount(bits[i]);
r += bitCount(bits[n] & ((1u << f)-1u));
return r;
}

void listPages(uint mip) {
const ivec3 size = imageSize(pageTbl);
if(any(greaterThanEqual(at, size)))
return;
const uint lane = gl_LocalInvocationIndex;
const ivec3 at = ivec3(gl_LocalInvocationID.xy, mip);

if(lane < bits.length())
bits[lane] = 0;
barrier();

const ivec2 sz = loadPageSize(at);
if(sz.x>0)
atomicOr(bits[lane/32], 1u<<(lane%32));
barrier();

if(sz.x>0) {
const uint id = pageListPrefix + bitCountShared(lane);
vsm.pageList[id] = packVsmPageInfo(at, sz);
}
barrier();
}

void main() {
const uint lane = gl_LocalInvocationIndex;
const uint mip = gl_WorkGroupID.x;

pageListPrefix = 0;
barrier();

if(lane<mip)
atomicAdd(pageListPrefix, vsm.header.pagePerMip[lane]);
barrier();

if(mip+1==VSM_PAGE_MIPS && lane==mip) {
vsm.header.pageCount = pageListPrefix + vsm.header.pagePerMip[lane];
}

uint v = imageLoad(pageTbl, at).x;
if(v==0)
if(vsm.header.pagePerMip[mip]==0)
return;

uint i = atomicAdd(vsm.header.pageCount, 1);
vsm.pageList[i] = 0xFFFFFFFF;
imageStore(pageTbl, at, uvec4(i));
listPages(mip);
}

0 comments on commit 05074bf

Please sign in to comment.