Skip to content

Commit

Permalink
vsm in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Sep 24, 2024
1 parent 2bb402d commit 18984d8
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 85 deletions.
1 change: 1 addition & 0 deletions game/graphics/drawcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ void DrawCommands::updateTasksUniforms() {
} else {
i.desc.set(T_Scene, scene.uboGlobal[i.viewport]);
i.desc.set(T_Payload, views[i.viewport].vsmClusters);
i.desc.set(T_HiZ, *scene.vsmPageHiZ);
i.desc.set(T_VsmPages, *scene.vsmPageList);
// i.desc.set(T_PkgOffsets, views[i.viewport].pkgOffsets);
}
Expand Down
15 changes: 10 additions & 5 deletions game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,9 @@ void Renderer::resetSwapchain() {

vsm.pageDbg = device.image2d(TextureFormat::R32U, 32, 32);
vsm.pageTbl = device.image3d(TextureFormat::R32U, 32, 32, 16);
// vsm.pageDataCs = device.image2d(TextureFormat::R32U, 4096, 4096);
vsm.pageHiZ = device.image3d(TextureFormat::R32U, 32, 32, 16);
vsm.pageData = device.zbuffer(shadowFormat, 4096, 4096);
// vsm.pageDataCs = device.image2d(TextureFormat::R32U, 4096, 4096);

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);
Expand Down Expand Up @@ -451,6 +452,7 @@ void Renderer::prepareUniforms() {
if(settings.vsmEnabled) {
vsm.uboClear.set(0, vsm.pageList);
vsm.uboClear.set(1, vsm.pageTbl);
vsm.uboClear.set(2, vsm.pageHiZ);

if(!vsm.uboClearPages.isEmpty())
vsm.uboClearPages.set(0, vsm.pageDataCs);
Expand All @@ -460,6 +462,8 @@ void Renderer::prepareUniforms() {
vsm.uboPages.set(2, gbufNormal, Sampler::nearest());
vsm.uboPages.set(3, zbuffer, Sampler::nearest());
vsm.uboPages.set(4, vsm.pageTbl);
vsm.uboPages.set(6, vsm.pageHiZ);
//vsm.uboPages.set(7, vsm.pageList);

vsm.uboClump.set(0, vsm.pageList);
vsm.uboClump.set(1, vsm.pageTbl);
Expand All @@ -476,6 +480,7 @@ void Renderer::prepareUniforms() {
if(!vsm.pageDataCs.isEmpty())
vsm.uboLight.set(5, vsm.pageDataCs); else
vsm.uboLight.set(5, vsm.pageData);
vsm.uboLight.set(7, vsm.pageList);

vsm.uboDbg.set(0, wview->sceneGlobals().uboGlobal[SceneGlobals::V_Main]);
vsm.uboDbg.set(1, gbufDiffuse, Sampler::nearest());
Expand All @@ -499,7 +504,7 @@ void Renderer::prepareUniforms() {
sh[i] = &textureCast<const Texture2d&>(shadowMap[i]);
}
wview->setShadowMaps(sh);
wview->setVirtualShadowMap(vsm.pageDataCs, vsm.pageTbl, vsm.pageList);
wview->setVirtualShadowMap(vsm.pageDataCs, vsm.pageTbl, vsm.pageHiZ, vsm.pageList);
wview->setSwRenderingImage(swr.outputImage);

wview->setHiZ(textureCast<const Texture2d&>(hiz.hiZ));
Expand Down Expand Up @@ -774,7 +779,7 @@ void Renderer::drawVsmDbg(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t

cmd.setFramebuffer({{sceneLinear, Tempest::Preserve, Tempest::Preserve}});
cmd.setDebugMarker("VSM-dbg");
cmd.setUniforms(*vsm.pagesDbgPso, vsm.uboDbg);
cmd.setUniforms(*vsm.pagesDbgPso, vsm.uboDbg, &settings.vsmMipBias, sizeof(settings.vsmMipBias));
cmd.draw(Resources::fsqVbo());
}

Expand Down Expand Up @@ -864,7 +869,7 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fI
cmd.setUniforms(shaders.vsmClear, vsm.uboClear);
cmd.dispatchThreads(size_t(vsm.pageTbl.w()), size_t(vsm.pageTbl.h()), size_t(vsm.pageTbl.d()));

cmd.setUniforms(shaders.vsmMarkPages, vsm.uboPages);
cmd.setUniforms(shaders.vsmMarkPages, vsm.uboPages, &settings.vsmMipBias, sizeof(settings.vsmMipBias));
cmd.dispatchThreads(zbuffer.size());

if(vsm.pageDataCs.isEmpty()) {
Expand Down Expand Up @@ -961,7 +966,7 @@ void Renderer::drawShadowResolve(Encoder<CommandBuffer>& cmd, uint8_t fId, const
return;
if(settings.vsmEnabled) {
cmd.setDebugMarker("DirectSunLight-VSM");
cmd.setUniforms(*vsm.directLightPso, vsm.uboLight);
cmd.setUniforms(*vsm.directLightPso, vsm.uboLight, &settings.vsmMipBias, sizeof(settings.vsmMipBias));
cmd.draw(Resources::fsqVbo());
return;
}
Expand Down
3 changes: 3 additions & 0 deletions game/graphics/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class Renderer final {
float zVidGamma = 0.5;

float vidResIndex = 0;

float vsmMipBias = -0.25;
} settings;

Frustrum frustrum[SceneGlobals::V_Count];
Expand Down Expand Up @@ -225,6 +227,7 @@ class Renderer final {

Tempest::StorageImage pageDbg;
Tempest::StorageImage pageTbl;
Tempest::StorageImage pageHiZ;
Tempest::StorageImage pageDataCs;
Tempest::ZBuffer pageData;
Tempest::StorageBuffer pageList;
Expand Down
2 changes: 2 additions & 0 deletions game/graphics/sceneglobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,11 @@ void SceneGlobals::setShadowMap(const Tempest::Texture2d* tex[]) {

void SceneGlobals::setVirtualShadowMap(const Tempest::StorageImage& pageData,
const Tempest::StorageImage& pageTbl,
const Tempest::StorageImage& pageHiZ,
const Tempest::StorageBuffer& pageList) {
vsmPageData = &pageData;
vsmPageTbl = &pageTbl;
vsmPageHiZ = &pageHiZ;
vsmPageList = &pageList;
}

Expand Down
2 changes: 2 additions & 0 deletions game/graphics/sceneglobals.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class SceneGlobals final {

void setVirtualShadowMap(const Tempest::StorageImage& vsmPageData,
const Tempest::StorageImage& pageTbl,
const Tempest::StorageImage& pageHiZ,
const Tempest::StorageBuffer& vsmPageList);
void setSwRenderingImage(const Tempest::StorageImage& mainView);

Expand Down Expand Up @@ -77,6 +78,7 @@ class SceneGlobals final {

const Tempest::StorageImage* vsmPageData = nullptr;
const Tempest::StorageImage* vsmPageTbl = nullptr;
const Tempest::StorageImage* vsmPageHiZ = nullptr;
const Tempest::StorageBuffer* vsmPageList = nullptr;

const Tempest::StorageImage* swMainImage = nullptr;
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/worldview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ void WorldView::setShadowMaps(const Tempest::Texture2d* sh[]) {

void WorldView::setVirtualShadowMap(const Tempest::StorageImage& pageData,
const Tempest::StorageImage& pageTbl,
const Tempest::StorageImage& pageHiZ,
const Tempest::StorageBuffer& pageList) {
sGlobal.setVirtualShadowMap(pageData, pageTbl, pageList);
sGlobal.setVirtualShadowMap(pageData, pageTbl, pageHiZ, pageList);
}

void WorldView::setSwRenderingImage(const Tempest::StorageImage& mainView) {
Expand Down
5 changes: 4 additions & 1 deletion game/graphics/worldview.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ 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::StorageImage& pageTbl, const Tempest::StorageBuffer& pageList);
void setVirtualShadowMap(const Tempest::StorageImage& pageData,
const Tempest::StorageImage& pageTbl,
const Tempest::StorageImage& pageHiZ,
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);
Expand Down
2 changes: 1 addition & 1 deletion shader/virtual_shadow/vsm_alloc_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -243,5 +243,5 @@ void main() {
layoutPages(frag, size, 2);
layoutPages(frag, size, 1);

horizontalMerge();
//horizontalMerge();
}
3 changes: 3 additions & 0 deletions shader/virtual_shadow/vsm_clear.comp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ layout(binding = 0, std430) buffer CB0 {
uint pageList[];
};
layout(binding = 1, r32ui) uniform uimage3D pageTbl;
layout(binding = 2, r32ui) uniform uimage3D pageTblDepth;

void main() {
const ivec3 at = ivec3(gl_GlobalInvocationID);
Expand All @@ -22,6 +23,8 @@ void main() {
return;

imageStore(pageTbl, at, uvec4(0));
imageStore(pageTblDepth, at, uvec4(0xFFFFFFFF));

if(at==ivec3(0)) {
header.pageCount = 0;
header.meshletCount = 0;
Expand Down
158 changes: 87 additions & 71 deletions shader/virtual_shadow/vsm_clump_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,59 @@ layout(binding = 0, std430) buffer Pages { VsmHeader header; uint pageList[]; }
layout(binding = 1, r32ui) uniform uimage3D pageTbl;

shared uint minY;
shared uint minX [32/2];
shared uint sWidth[32/2];
shared uint minX [gl_WorkGroupSize.y/4];
shared uint sWidth[gl_WorkGroupSize.y/4];
shared uint data[gl_WorkGroupSize.x][gl_WorkGroupSize.y];

void storePage(ivec3 at, uint samples, uint size) {
uint d = (samples & 0xFF) | (size << 8);
imageStore(pageTbl, at, uvec4(d));
uint packPage(uint samples, uint size, uint prime) {
return (samples & 0xFF) | (size << 8) | (prime << 16);
}

uvec2 loadPage(ivec3 at) {
uint a = imageLoad(pageTbl, at).r;
return uvec2(a&0xFF, a>>8);
uint packPage(uint samples, uint size) {
return (samples & 0xFF) | (size << 8);
}

uint loadPagePrimeSize(ivec3 at) {
uint a = imageLoad(pageTbl, at).r;
return a >> 1;
uint unpackSize(uint a){
return (a >> 8) & 0xFF;
}

uint loadPagePrimeBit(ivec3 at) {
uint a = imageLoad(pageTbl, at).r;
return a & 0x1;
uint unpackSamples(uint a){
return a&0xFF;
}

void storePagePrime(ivec3 at, uint size, uint prime) {
uint d = (size << 1) | prime&0x1;
imageStore(pageTbl, at, uvec4(d));
uint unpackPrimeBit(uint a){
return (a >> 16) & 0x1;
}

void poolPageTable() {
const ivec3 size = imageSize(pageTbl);
const ivec3 at = ivec3(gl_GlobalInvocationID);
const ivec3 id = ivec3(gl_LocalInvocationID);

if(all(lessThan(at, size))) {
const uint frag = imageLoad(pageTbl, at).r;
//data[id.x][id.y] = frag;
data[at.x][at.y] = packPage(frag, frag, frag);
} else {
data[id.x][id.y] = 0;
}
barrier();
}

void storePageTable() {
barrier();

const ivec3 size = imageSize(pageTbl);
const ivec3 at = ivec3(gl_GlobalInvocationID);
const ivec3 id = ivec3(gl_LocalInvocationID);

if(all(lessThan(at, size))) {
uint d = data[at.x][at.y];
uint p = unpackPrimeBit(d);
//uint s = p>0 ? unpackSize(d) : 0;
uint s = unpackSize(d);
imageStore(pageTbl, at, uvec4((s<<1) | p) );
}
}

void main() {
Expand All @@ -48,17 +75,18 @@ void main() {
const ivec3 id = ivec3(gl_LocalInvocationID);
const uint lane = gl_LocalInvocationIndex;

poolPageTable();

if(lane < minX.length()) {
minX [lane] = 0xFFFF;
sWidth[lane] = 0;
}
minY = 0xFFFF;
barrier();

const uint frag = imageLoad(pageTbl, at).r;
const uint frag = data[at.x][at.y];
const bool prime = frag>0;

if(frag>0) {
if(prime) {
atomicMin(minY, at.y);

atomicMin(vsm.header.pageBbox[at.z].x, at.x);
Expand All @@ -68,85 +96,73 @@ void main() {
}
barrier();

const uint stripe = (at.y-minY)/2;
const uint stripe = (at.y-minY)/4;
if(frag>0)
atomicMin(minX[stripe], at.x);
barrier();

if(stripe%2==1 && minX[stripe-1]%2!=minX[stripe]%2) {
if(minX[stripe-1] > minX[stripe])
minX[stripe-1]--; else
minX[stripe-0]--;
}
const ivec2 tileCoord = ivec2(at.x - minX[stripe], at.y-minY);
if(frag>0)
atomicMax(sWidth[stripe], tileCoord.x + 1);
barrier();

ivec2 tileCoord = ivec2(at.x - minX[stripe], at.y-minY);
if(frag>0) {
uint w = tileCoord.x + 1;
w += w%2;
atomicMax(sWidth[stripe], w);
const bool valid = (0<=tileCoord.x && tileCoord.x<sWidth[stripe] && 0<=tileCoord.y);
const bool quad = (valid && tileCoord.x%2==0 && tileCoord.y%2==0 && at.x<size.x-1 && at.y<size.y-1);
const bool bQuad = (valid && tileCoord.x%4==0 && tileCoord.y%4==0 && at.x<size.x-2 && at.y<size.y-2);
if(true && quad) {
uint a = unpackPrimeBit(data[at.x+0][at.y+0]);
uint b = unpackPrimeBit(data[at.x+1][at.y+0]);
uint c = unpackPrimeBit(data[at.x+1][at.y+1]);
uint d = unpackPrimeBit(data[at.x+0][at.y+1]);
data[at.x][at.y] = packPage(a+b+c+d, 2);
}
barrier();

const bool valid = (0<=tileCoord.x && tileCoord.x<sWidth[stripe] && 0<=tileCoord.y);
const bool quad = (valid && tileCoord.x%2==0 && tileCoord.y%2==0);
const bool bQuad = (valid && tileCoord.x%4==0 && tileCoord.y%4==0);
if(quad) {
uint a = loadPagePrimeBit(at+ivec3(0,0,0));
uint b = loadPagePrimeBit(at+ivec3(1,0,0));
uint c = loadPagePrimeBit(at+ivec3(1,1,0));
uint d = loadPagePrimeBit(at+ivec3(0,1,0));
//storePage(at, (a+b+c+d));
storePage(at, (a+b+c+d), 2);
} else {
storePage(at, 0, 0);
}
memoryBarrierImage();
if(!quad)
data[at.x][at.y] = packPage(0,0);
barrier();

if(true && bQuad) {
const int mergeQ = (at.z>4 ? 2 : 3)*2;
uint a = loadPage(at+ivec3(0,0,0)).x;
uint b = loadPage(at+ivec3(2,0,0)).x;
uint c = loadPage(at+ivec3(2,2,0)).x;
uint d = loadPage(at+ivec3(0,2,0)).x;
uint a = unpackSamples(data[at.x+0][at.y+0]);
uint b = unpackSamples(data[at.x+2][at.y+0]);
uint c = unpackSamples(data[at.x+2][at.y+2]);
uint d = unpackSamples(data[at.x+0][at.y+2]);
uint s = (a+b+c+d);
if(a+b+c+d >= mergeQ) {
storePage(at+ivec3(0,0,0), s, 4);
storePage(at+ivec3(2,0,0), 0, 0);
storePage(at+ivec3(0,2,0), 0, 0);
storePage(at+ivec3(2,2,0), 0, 0);
data[at.x+0][at.y+0] = packPage(s, 4);
data[at.x+2][at.y+0] = packPage(0, 0);
data[at.x+0][at.y+2] = packPage(0, 0);
data[at.x+2][at.y+2] = packPage(0, 0);
}
}
barrier();

// prime bit
memoryBarrierImage();
barrier();
{
uint data = loadPage(at).y;
data = (data << 1) | (prime ? 1 : 0);
imageStore(pageTbl, at, uvec4(data));
uint d = unpackSamples(data[at.x][at.y]);
uint s = unpackSize (data[at.x][at.y]);
data[at.x][at.y] = packPage(d ,s, prime ? 1 : 0);
}

// demote unfilled quads to 1x1 pages
memoryBarrierImage();
barrier();

// demote unfilled quads to 1x1 pages
if(true && quad) {
uint s = loadPagePrimeSize(at);
uint a = loadPagePrimeBit (at+ivec3(0,0,0));
uint b = loadPagePrimeBit (at+ivec3(1,0,0));
uint c = loadPagePrimeBit (at+ivec3(1,1,0));
uint d = loadPagePrimeBit (at+ivec3(0,1,0));
uint s = unpackSize (data[at.x][at.y]);
uint a = unpackPrimeBit(data[at.x+0][at.y+0]);
uint b = unpackPrimeBit(data[at.x+1][at.y+0]);
uint c = unpackPrimeBit(data[at.x+1][at.y+1]);
uint d = unpackPrimeBit(data[at.x+0][at.y+1]);
if(s==2 && a+b+c+d <= 2) {
storePagePrime(at+ivec3(0,0,0), a, a);
storePagePrime(at+ivec3(1,0,0), b, b);
storePagePrime(at+ivec3(1,1,0), c, c);
storePagePrime(at+ivec3(0,1,0), d, d);
data[at.x+0][at.y+0] = packPage(1, a, a);
data[at.x+1][at.y+0] = packPage(1, b, b);
data[at.x+1][at.y+1] = packPage(1, c, c);
data[at.x+0][at.y+1] = packPage(1, d, d);
}
}
}

storePageTable();
}

/*
void trimMip(int mip) {
Expand Down
Loading

0 comments on commit 18984d8

Please sign in to comment.