Skip to content

Commit

Permalink
vsm: pages 4x4
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Sep 15, 2024
1 parent 5da50d1 commit 690905f
Show file tree
Hide file tree
Showing 20 changed files with 208 additions and 38 deletions.
13 changes: 7 additions & 6 deletions game/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,17 @@ Matrix4x4 Camera::viewShadowLwc(const Tempest::Vec3& lightDir, size_t layer) con
return mkViewShadow(cameraPos-origin,rotation,vp,lightDir,layer);
}

Matrix4x4 Camera::viewShadowVsm(const Tempest::Vec3& lightDir) const {
auto vp = viewProj();
float rotation = (180+src.spin.y-rotOffset.y);
return viewShadowVsm(cameraPos,rotation,vp,lightDir);
Matrix4x4 Camera::viewShadowVsm(const Tempest::Vec3& ldir) const {
return mkViewShadowVsm(cameraPos,ldir);
}

Matrix4x4 Camera::viewShadowVsmLwc(const Tempest::Vec3& ldir) const {
return mkViewShadowVsm(cameraPos-origin,ldir);
}

Matrix4x4 Camera::viewShadowVsm(const Vec3& cameraPos, float rotation, const Tempest::Matrix4x4& viewProj, const Vec3& ldir) const {
Matrix4x4 Camera::mkViewShadowVsm(const Vec3& cameraPos, const Vec3& ldir) const {
float smWidth = 1024; // ~4 pixels per santimeter
float smDepth = 5*5120;
(void)rotation;

float smWidthInv = 1.f/smWidth;
float zScale = 1.f/smDepth;
Expand Down
3 changes: 2 additions & 1 deletion game/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Camera final {
Tempest::Matrix4x4 viewShadowLwc(const Tempest::Vec3& ldir, size_t layer) const;

Tempest::Matrix4x4 viewShadowVsm(const Tempest::Vec3& ldir) const;
Tempest::Matrix4x4 viewShadowVsm(const Tempest::Vec3& cameraPos, float rotation, const Tempest::Matrix4x4& viewProj, const Tempest::Vec3& ldir) const;
Tempest::Matrix4x4 viewShadowVsmLwc(const Tempest::Vec3& ldir) const;

ListenerPos listenerPosition() const;
Tempest::Vec3 originLwc() const { return origin; };
Expand Down Expand Up @@ -175,6 +175,7 @@ class Camera final {
Tempest::Matrix4x4 mkRotation(const Tempest::Vec3& spin) const;
Tempest::Matrix4x4 mkViewShadow(const Tempest::Vec3& cameraPos, float rotation,
const Tempest::Matrix4x4& viewProj, const Tempest::Vec3& lightDir, size_t layer) const;
Tempest::Matrix4x4 mkViewShadowVsm(const Tempest::Vec3& cameraPos, const Tempest::Vec3& ldir) const;
void resetDst();

void clampRotation(Tempest::Vec3& spin);
Expand Down
6 changes: 6 additions & 0 deletions game/commandline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ CommandLine::CommandLine(int argc, const char** argv) {
if(i<argc)
isBindlessSh = (std::string_view(argv[i])!="0" && std::string_view(argv[i])!="false");
}
else if(arg=="-vsm") {
// not to document - debug only
++i;
if(i<argc)
isVsm = (std::string_view(argv[i])!="0" && std::string_view(argv[i])!="false");
}
else {
Log::i("unreacognized commandline option: \"", arg, "\"");
}
Expand Down
2 changes: 2 additions & 0 deletions game/commandline.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class CommandLine {
bool isRtGi() const { return isGi; }
bool isMeshShading() const { return isMeshSh; }
bool isBindless() const { return isBindlessSh; }
bool isVirtualShadow() const { return isVsm; }
bool doStartMenu() const { return !noMenu; }
bool doForceG1() const { return forceG1; }
bool doForceG2() const { return forceG2; }
Expand Down Expand Up @@ -68,6 +69,7 @@ class CommandLine {
bool isMeshSh = true;
#endif
bool isBindlessSh = true;
bool isVsm = false;
bool isGi = false;
bool forceG1 = false;
bool forceG2 = false;
Expand Down
3 changes: 2 additions & 1 deletion game/gothic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ Gothic::Gothic() {
}

if(hasBindless() && gpu.compute.maxInvocations>=1024) {
opts.doVirtualShadow = false; //TODO: productize
//TODO: productize
opts.doVirtualShadow = CommandLine::inst().isVirtualShadow();
}

opts.aaPreset = CommandLine::inst().aaPreset();
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/drawcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ bool DrawCommands::commit() {
if(cmdChg) {
Resources::recycle(std::move(v.indirectCmd));
v.indirectCmd = device.ssbo(cx.data(), sizeof(IndirectCmd)*cx.size());
visChg |= (v.viewport==SceneGlobals::V_Vsm);
visChg |= (v.viewport==SceneGlobals::V_Vsm); //FIXME
}

Resources::recycle(std::move(v.descInit));
Expand Down
9 changes: 6 additions & 3 deletions game/graphics/renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ void Renderer::resetSwapchain() {
vsm.shadowMask = device.image2d(Tempest::RGBA8, w, h);

auto pageCount = uint32_t((vsm.pageData.w()+128-1)/128) * uint32_t((vsm.pageData.h()+128-1)/128);
vsm.pageList = device.ssbo(nullptr, (pageCount + 2)*sizeof(uint32_t));
vsm.pageList = device.ssbo(nullptr, (pageCount + 4)*sizeof(uint32_t));
}

if(settings.swrEnabled) {
Expand Down Expand Up @@ -618,7 +618,7 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
}
frustrum[SceneGlobals::V_Main].make(viewProj,zbuffer.w(),zbuffer.h());
frustrum[SceneGlobals::V_HiZ] = frustrum[SceneGlobals::V_Main];
frustrum[SceneGlobals::V_Vsm].make(shadowMatrixVsm, vsm.pageData.w(), vsm.pageData.h()); //TODO: remove
frustrum[SceneGlobals::V_Vsm] = frustrum[SceneGlobals::V_Shadow1]; //TODO: remove
wview->updateFrustrum(frustrum);
}

Expand Down Expand Up @@ -858,7 +858,10 @@ void Renderer::drawVsm(Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fI
cmd.setUniforms(*vsm.pagesMarkPso, vsm.uboPages);
cmd.dispatchThreads(zbuffer.size());

cmd.setUniforms(Shaders::inst().vsmClumpPages, vsm.uboList);
//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()));

cmd.setUniforms(*vsm.pagesListPso, vsm.uboList);
Expand Down
5 changes: 3 additions & 2 deletions game/graphics/sceneglobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ void SceneGlobals::setViewLwc(const Tempest::Matrix4x4& view, const Tempest::Mat
uboGlobalCpu.viewShadowLwc[i] = sh[i];
}

void SceneGlobals::setViewVsm(const Tempest::Matrix4x4& view) {
uboGlobalCpu.viewVirtualShadow = view;
void SceneGlobals::setViewVsm(const Tempest::Matrix4x4& view, const Tempest::Matrix4x4& viewLwc) {
uboGlobalCpu.viewVirtualShadow = view;
uboGlobalCpu.viewVirtualShadowLwc = viewLwc;
}

void SceneGlobals::setSky(const Sky& s) {
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/sceneglobals.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class SceneGlobals final {
float zNear, float zFar,
const Tempest::Matrix4x4 *sh);
void setViewLwc(const Tempest::Matrix4x4& view, const Tempest::Matrix4x4& proj, const Tempest::Matrix4x4 *sh);
void setViewVsm(const Tempest::Matrix4x4& view);
void setViewVsm(const Tempest::Matrix4x4& view, const Tempest::Matrix4x4& viewLwc);
void setSky(const Sky& s);
void setUnderWater(bool w);

Expand Down Expand Up @@ -86,6 +86,7 @@ class SceneGlobals final {
Tempest::Matrix4x4 viewProjectLwcInv;
Tempest::Matrix4x4 viewShadowLwc[Resources::ShadowLayers];
Tempest::Matrix4x4 viewVirtualShadow;
Tempest::Matrix4x4 viewVirtualShadowLwc;
Tempest::Matrix4x4 view, project, projectInv;
Tempest::Vec3 sunDir = {0,0,1};
float waveAnim = 0;
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ Shaders::Shaders() {
vsmClusterTask = computeShader("vsm_cluster_task.comp.sprv");
vsmClear = computeShader("vsm_clear.comp.sprv");
vsmMarkPages = computeShader("vsm_mark_pages.comp.sprv");
vsmClumpPages = computeShader("vsm_clump_pages.comp.sprv");
vsmClumpPages0 = computeShader("vsm_clump_pages0.comp.sprv");
vsmClumpPages1 = computeShader("vsm_clump_pages1.comp.sprv");
vsmListPages = computeShader("vsm_list_pages.comp.sprv");
vsmSortPages = computeShader("vsm_sort_pages.comp.sprv");
vsmPackDraw0 = computeShader("vsm_pack_draws0.comp.sprv");
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class Shaders {

// Virtual shadow
Tempest::ComputePipeline vsmClusterTask;
Tempest::ComputePipeline vsmClear, vsmMarkPages, vsmClumpPages, vsmListPages;
Tempest::ComputePipeline vsmClear, vsmMarkPages, vsmListPages;
Tempest::ComputePipeline vsmClumpPages0, vsmClumpPages1;
Tempest::ComputePipeline vsmPackDraw0, vsmPackDraw1;
Tempest::RenderPipeline vsmDirectLight;
Tempest::ComputePipeline vsmSortPages;
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/worldview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void WorldView::preFrameUpdate(const Camera& camera, uint64_t tickCount, uint8_t
sGlobal.setSky(gSky);
sGlobal.setViewProject(camera.view(),camera.projective(),camera.zNear(),camera.zFar(),shadow);
sGlobal.setViewLwc(camera.viewLwc(),camera.projective(),shadowLwc);
sGlobal.setViewVsm(camera.viewShadowVsm(ldir));
sGlobal.setViewVsm(camera.viewShadowVsm(ldir), camera.viewShadowVsmLwc(ldir));
sGlobal.originLwc = camera.originLwc();
sGlobal.setUnderWater(camera.isInWater());

Expand Down
9 changes: 5 additions & 4 deletions shader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,12 @@ add_shader(cmaa2_deferred_color_apply_2x2.vert antialiasing/cmaa2/deferred_c
add_shader(cmaa2_deferred_color_apply_2x2.frag antialiasing/cmaa2/deferred_color_apply_2x2.frag)

# virtual shadows
add_shader(direct_light_vsm.frag virtual_shadow/vsm_mark_pages.comp -DCOMPOSE -S frag)
add_shader(vsm_dbg.frag virtual_shadow/vsm_mark_pages.comp -DDEBUG -S frag)
add_shader(direct_light_vsm.frag virtual_shadow/vsm_mark_pages.comp -DCOMPOSE -DLWC -S frag)
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_mark_pages.comp virtual_shadow/vsm_mark_pages.comp -DMARK_PAGES)
add_shader(vsm_clump_pages.comp virtual_shadow/vsm_clump_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)
add_shader(vsm_sort_pages.comp virtual_shadow/vsm_sort_pages.comp)
add_shader(vsm_pack_draws0.comp virtual_shadow/vsm_pack_draws.comp -DPASS0)
Expand Down
1 change: 1 addition & 0 deletions shader/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct SceneDesc {
mat4 viewProjectLwcInv;
mat4 viewShadowLwc[2];
mat4 viewVirtualShadow;
mat4 viewVirtualShadowLwc;
mat4 view;
mat4 project;
mat4 projectInv;
Expand Down
2 changes: 2 additions & 0 deletions shader/virtual_shadow/vsm_clear.comp
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ void main() {
if(at==ivec3(0)) {
header.pageCount = 0;
header.meshletCount = 0;
header.counterM = 0;
header.counterV = 0;
}
}
86 changes: 85 additions & 1 deletion shader/virtual_shadow/vsm_clump_pages.comp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,97 @@
#include "scene.glsl"
#include "common.glsl"

#if defined(PASS0)
layout(local_size_x = 16, local_size_y = 8) in;
#else
layout(local_size_x = 8, local_size_y = 8) in;
#endif

layout(binding = 0, std430) buffer Pages { VsmHeader header; uint pageList[]; } vsm;
layout(binding = 1, r32ui) uniform uimage3D pageTbl;

shared uint pageVal[gl_WorkGroupSize.x][gl_WorkGroupSize.y];
void trimMip(int mip) {
const ivec3 size = imageSize(pageTbl);
const ivec3 id = ivec3(gl_LocalInvocationID);

const ivec2 b = ivec2(VSM_PAGE_TBL_SIZE/4);
const ivec2 h = ivec2(VSM_PAGE_TBL_SIZE/2);

for(int i=id.x; i<h.x; i+=int(gl_WorkGroupSize.x)) {
for(int r=id.y; r<h.y; r+=int(gl_WorkGroupSize.y)) {
ivec3 ax = ivec3(i+b.x, r+b.y, mip);
uint st = imageLoad(pageTbl, ax).r;
if(st==0)
continue;

ivec3 at = ivec3(i*2, r*2, mip-1);
uint a = imageLoad(pageTbl, at+ivec3(0,0,0)).r;
uint b = imageLoad(pageTbl, at+ivec3(1,0,0)).r;
uint c = imageLoad(pageTbl, at+ivec3(0,1,0)).r;
uint d = imageLoad(pageTbl, at+ivec3(1,1,0)).r;
if(a>0 && b>0 && c>0 && d>0) {
imageStore(pageTbl, ax, uvec4(0));
}
}
}
}

void mainTrim() {
const ivec3 size = imageSize(pageTbl);
// NOTE: need only about 5 mips
for(int i=1; i<size.z; ++i) {
trimMip(i);
barrier();
}
}

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

if(true && at.x%2==0 && at.y%2==0) {
uint a = imageLoad(pageTbl, at+ivec3(0,0,0)).r;
uint b = imageLoad(pageTbl, at+ivec3(1,0,0)).r;
uint c = imageLoad(pageTbl, at+ivec3(1,1,0)).r;
uint d = imageLoad(pageTbl, at+ivec3(0,1,0)).r;
if(a==1 && b==1 && c==1 && d==1) {
imageStore(pageTbl, at+ivec3(0,0,0), uvec4(2));
imageStore(pageTbl, at+ivec3(1,0,0), uvec4(0));
imageStore(pageTbl, at+ivec3(0,1,0), uvec4(0));
imageStore(pageTbl, at+ivec3(1,1,0), uvec4(0));
}
}
groupMemoryBarrier();
barrier();

if(true && 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==2 && b==2 && c==2 && d==2) {
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));
imageStore(pageTbl, at+ivec3(2,2,0), uvec4(0));
}
}
}

void main() {
#if defined(PASS0)
mainTrim();
#elif defined(PASS1)
mainGroups();
#else
#error "invalid pass-id"
#endif
}

/*
shared uint pageVal[gl_WorkGroupSize.x][gl_WorkGroupSize.y];
void main2() {
const ivec3 size = imageSize(pageTbl);
const ivec3 at = ivec3(gl_GlobalInvocationID);
const ivec3 id = ivec3(gl_LocalInvocationID);
Expand Down Expand Up @@ -70,3 +153,4 @@ void main() {
imageStore(pageTbl, at+ivec3(1,1,0), uvec4(0));
}
}
*/
24 changes: 22 additions & 2 deletions shader/virtual_shadow/vsm_cluster_task.comp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ layout(push_constant, std430) uniform UboPush {
int meshletCount;
} push;

shared bool workgroupBool;

bool workgroupAny(bool a) {
workgroupBool = false;
barrier();
if(a)
workgroupBool = true;
barrier();
return workgroupBool;
}

bool projectSphere(const vec4 sphere, out vec4 aabb, out float depthMin) {
const vec3 c = (scene.viewProject * vec4(sphere.xyz, 1)).xyz;
const float R = sphere.w;
Expand Down Expand Up @@ -109,8 +120,12 @@ void runCluster(const uint clusterId) {
if(cluster.sphere.w<=0.f)
return; // disabled or deleted

//if(!frustrumTest(cluster.sphere))
// return;
if(frustrumTest(cluster.sphere)) {
if(gl_LocalInvocationIndex==0)
atomicAdd(vsm.header.counterV, cluster.meshletCount);
} else {
// return;
}

vec4 aabb = vec4(0);
float depthMin = 1;
Expand All @@ -119,6 +134,7 @@ void runCluster(const uint clusterId) {

const uint commandId = cluster.bucketId_commandId & 0xFFFF;
const uint pageCount = vsm.header.pageCount;
bool anyPage = false;

for(uint i=gl_LocalInvocationIndex; i<pageCount; i+=gl_WorkGroupSize.y) {
// if(i!=13)
Expand All @@ -135,7 +151,11 @@ void runCluster(const uint clusterId) {
if(!emitCluster(cluster, i))
break;
atomicAdd(cmd[commandId].instanceCount, cluster.meshletCount);
anyPage = true;
}

if(workgroupAny(anyPage) && gl_LocalInvocationIndex==0)
atomicAdd(vsm.header.counterM, cluster.meshletCount);
}

void main() {
Expand Down
2 changes: 2 additions & 0 deletions shader/virtual_shadow/vsm_common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const int VSM_CLIPMAP_SIZE = VSM_PAGE_SIZE * VSM_PAGE_TBL_SIZE;
struct VsmHeader {
uint pageCount;
uint meshletCount;
uint counterM;
uint counterV;
};

uint packVsmPageInfo(ivec3 at, ivec2 size) {
Expand Down
Loading

0 comments on commit 690905f

Please sign in to comment.