Skip to content

Commit

Permalink
vsm: fragment atomics path
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Sep 18, 2024
1 parent 4e096ff commit 8583221
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 32 deletions.
12 changes: 10 additions & 2 deletions game/graphics/drawcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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());
Expand Down
6 changes: 4 additions & 2 deletions game/graphics/drawcommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -147,6 +149,6 @@ class DrawCommands {
View views[SceneGlobals::V_Count];

Tempest::StorageBuffer vsmIndirectCmd;
Tempest::StorageImage vsmSwrImage;
// Tempest::StorageImage vsmSwrImage;
Tempest::DescriptorSet vsmDesc;
};
35 changes: 24 additions & 11 deletions game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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());
Expand All @@ -466,16 +471,16 @@ 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());
vsm.uboDbg.set(2, gbufNormal, Sampler::nearest());
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) {
Expand All @@ -492,7 +497,7 @@ void Renderer::prepareUniforms() {
sh[i] = &textureCast<const Texture2d&>(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<const Texture2d&>(hiz.hiZ));
Expand Down Expand Up @@ -859,12 +864,20 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& 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()));
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions game/graphics/sceneglobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions game/graphics/sceneglobals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/worldview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/worldview.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 20 additions & 1 deletion shader/materials/main.frag
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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)
Expand Down
43 changes: 41 additions & 2 deletions shader/materials/main.vert
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down
13 changes: 11 additions & 2 deletions shader/materials/materials_common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions shader/virtual_shadow/vsm_clear.comp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Loading

0 comments on commit 8583221

Please sign in to comment.