From 8beff1fd7ff699bba84f9b10725509417520eb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sun, 8 Feb 2026 08:37:48 +0000 Subject: [PATCH] Emitter, surfelgi, GPU sort refactor (#1541) --- WickedEngine/shaders/ShaderInterop.h | 2 + .../shaders/ShaderInterop_EmittedParticle.h | 20 +++--- .../shaders/ShaderInterop_GPUSortLib.h | 9 ++- WickedEngine/shaders/ShaderInterop_SurfelGI.h | 17 +++-- WickedEngine/shaders/bvh_hierarchyCS.hlsl | 4 +- WickedEngine/shaders/bvh_propagateaabbCS.hlsl | 4 +- WickedEngine/shaders/emittedparticleMS.hlsl | 4 +- .../shaders/emittedparticle_emitCS.hlsl | 6 +- .../emittedparticle_finishUpdateCS.hlsl | 4 +- .../emittedparticle_kickoffUpdateCS.hlsl | 16 ++--- .../shaders/emittedparticle_simulateCS.hlsl | 10 +-- .../shaders/emittedparticle_sphbinningCS.hlsl | 4 +- .../emittedparticle_sphcellallocationCS.hlsl | 4 +- .../shaders/emittedparticle_sphdensityCS.hlsl | 4 +- .../shaders/emittedparticle_sphforceCS.hlsl | 4 +- .../emittedparticle_sphpartitionCS.hlsl | 4 +- .../shaders/gpusortlib_kickoffSortCS.hlsl | 23 +++--- WickedEngine/shaders/gpusortlib_sortCS.hlsl | 5 +- .../shaders/gpusortlib_sortInnerCS.hlsl | 13 +--- .../shaders/gpusortlib_sortStepCS.hlsl | 10 ++- WickedEngine/shaders/raytracingHF.hlsli | 12 ++-- WickedEngine/shaders/surfel_binningCS.hlsl | 4 +- WickedEngine/shaders/surfel_coverageCS.hlsl | 6 +- .../shaders/surfel_gridoffsetsCS.hlsl | 4 +- .../shaders/surfel_indirectprepareCS.hlsl | 20 +++--- WickedEngine/shaders/surfel_raytraceCS.hlsl | 4 +- WickedEngine/shaders/surfel_updateCS.hlsl | 12 ++-- WickedEngine/wiEmittedParticle.cpp | 9 +-- WickedEngine/wiGPUBVH.cpp | 31 ++++---- WickedEngine/wiGPUSortLib.cpp | 71 +++++++++---------- WickedEngine/wiGPUSortLib.h | 8 +-- WickedEngine/wiGraphicsDevice_DX12.cpp | 2 +- WickedEngine/wiRenderer.cpp | 9 ++- WickedEngine/wiScene.cpp | 11 +-- WickedEngine/wiVersion.cpp | 2 +- 35 files changed, 190 insertions(+), 182 deletions(-) diff --git a/WickedEngine/shaders/ShaderInterop.h b/WickedEngine/shaders/ShaderInterop.h index f0de639c0..b5aa12ad0 100644 --- a/WickedEngine/shaders/ShaderInterop.h +++ b/WickedEngine/shaders/ShaderInterop.h @@ -109,6 +109,7 @@ struct IndirectDispatchArgs #define CBSLOT_MSAO 4 #define CBSLOT_FSR 4 #define CBSLOT_TRAILRENDERER 3 +#define CBSLOT_GPUSORTLIB 2 #else // Don't use overlapping slots on PS5: @@ -136,6 +137,7 @@ struct IndirectDispatchArgs #define CBSLOT_MSAO 4 #define CBSLOT_FSR 4 #define CBSLOT_TRAILRENDERER 4 +#define CBSLOT_GPUSORTLIB 4 #endif // !__PSSL__ && !__SCE__ #endif // WI_SHADERINTEROP_H diff --git a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h index 0eb738ef9..4e165d86a 100644 --- a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h +++ b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h @@ -26,18 +26,16 @@ struct ParticleCounters uint culledCount; uint cellAllocator; }; -static const uint PARTICLECOUNTER_OFFSET_ALIVECOUNT = 0; -static const uint PARTICLECOUNTER_OFFSET_DEADCOUNT = PARTICLECOUNTER_OFFSET_ALIVECOUNT + 4; -static const uint PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION = PARTICLECOUNTER_OFFSET_DEADCOUNT + 4; -static const uint PARTICLECOUNTER_OFFSET_CULLEDCOUNT = PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION + 4; -static const uint PARTICLECOUNTER_OFFSET_CELLALLOCATOR = PARTICLECOUNTER_OFFSET_CULLEDCOUNT + 4; -static const uint EMITTER_OPTION_BIT_FRAME_BLENDING_ENABLED = 1 << 0; -static const uint EMITTER_OPTION_BIT_SPH_ENABLED = 1 << 1; -static const uint EMITTER_OPTION_BIT_MESH_SHADER_ENABLED = 1 << 2; -static const uint EMITTER_OPTION_BIT_COLLIDERS_DISABLED = 1 << 3; -static const uint EMITTER_OPTION_BIT_USE_RAIN_BLOCKER = 1 << 4; -static const uint EMITTER_OPTION_BIT_TAKE_COLOR_FROM_MESH = 1 << 5; +enum EMITTER_OPTIONS +{ + EMITTER_OPTION_BIT_FRAME_BLENDING_ENABLED = 1 << 0, + EMITTER_OPTION_BIT_SPH_ENABLED = 1 << 1, + EMITTER_OPTION_BIT_MESH_SHADER_ENABLED = 1 << 2, + EMITTER_OPTION_BIT_COLLIDERS_DISABLED = 1 << 3, + EMITTER_OPTION_BIT_USE_RAIN_BLOCKER = 1 << 4, + EMITTER_OPTION_BIT_TAKE_COLOR_FROM_MESH = 1 << 5, +}; CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE) { diff --git a/WickedEngine/shaders/ShaderInterop_GPUSortLib.h b/WickedEngine/shaders/ShaderInterop_GPUSortLib.h index ea6fdb307..fd75c3558 100644 --- a/WickedEngine/shaders/ShaderInterop_GPUSortLib.h +++ b/WickedEngine/shaders/ShaderInterop_GPUSortLib.h @@ -6,8 +6,13 @@ struct SortConstants { int3 job_params; - uint counterReadOffset; + uint padding; }; -PUSHCONSTANT(sort, SortConstants); + +struct SortCount +{ + uint count; +}; +CONSTANTBUFFER(counterBuffer, SortCount, CBSLOT_GPUSORTLIB); #endif // WI_SHADERINTEROP_GPUSORTLIB_H diff --git a/WickedEngine/shaders/ShaderInterop_SurfelGI.h b/WickedEngine/shaders/ShaderInterop_SurfelGI.h index 2ad0d6245..d993e133e 100644 --- a/WickedEngine/shaders/ShaderInterop_SurfelGI.h +++ b/WickedEngine/shaders/ShaderInterop_SurfelGI.h @@ -12,13 +12,6 @@ static const uint SURFEL_TABLE_SIZE = SURFEL_GRID_DIMENSIONS.x * SURFEL_GRID_DIM static const float SURFEL_MAX_RADIUS = 2; static const float SURFEL_RECYCLE_DISTANCE = 0; // if surfel is behind camera and farther than this distance, it starts preparing for recycling static const uint SURFEL_RECYCLE_TIME = 60; // if surfel is preparing for recycling, this is how many frames it takes to recycle it. -static const uint SURFEL_STATS_OFFSET_COUNT = 0; -static const uint SURFEL_STATS_OFFSET_NEXTCOUNT = SURFEL_STATS_OFFSET_COUNT + 4; -static const uint SURFEL_STATS_OFFSET_DEADCOUNT = SURFEL_STATS_OFFSET_NEXTCOUNT + 4; -static const uint SURFEL_STATS_OFFSET_CELLALLOCATOR = SURFEL_STATS_OFFSET_DEADCOUNT + 4; -static const uint SURFEL_STATS_OFFSET_RAYCOUNT = SURFEL_STATS_OFFSET_CELLALLOCATOR + 4; -static const uint SURFEL_STATS_OFFSET_SHORTAGE = SURFEL_STATS_OFFSET_RAYCOUNT + 4; -static const uint SURFEL_STATS_SIZE = SURFEL_STATS_OFFSET_SHORTAGE + 4; static const uint SURFEL_INDIRECT_NUMTHREADS = 32; static const float SURFEL_TARGET_COVERAGE = 0.8f; // how many surfels should affect a pixel fully, higher values will increase quality and cost static const uint SURFEL_CELL_LIMIT = ~0; // limit the amount of allocated surfels in a cell @@ -28,6 +21,16 @@ static const uint SURFEL_RAY_BOOST_MAX = 64; // max amount of rays per surfel #define SURFEL_USE_HASHING // if defined, hashing will be used to retrieve surfels, hashing is good because it supports infinite world trivially, but slower due to hash collisions #define SURFEL_ENABLE_INFINITE_BOUNCES // if defined, previous frame's surfel data will be sampled at ray tracing hit points +struct SurfelStats +{ + uint count; + uint nextCount; + int deadCount; + uint cellAllocator; + uint rayCount; + int shortage; +}; + struct SurfelIndirectArgs { IndirectDispatchArgs iterate; diff --git a/WickedEngine/shaders/bvh_hierarchyCS.hlsl b/WickedEngine/shaders/bvh_hierarchyCS.hlsl index 747d728e3..4f4119149 100644 --- a/WickedEngine/shaders/bvh_hierarchyCS.hlsl +++ b/WickedEngine/shaders/bvh_hierarchyCS.hlsl @@ -12,7 +12,7 @@ // in "Maximizing Parallelism in the Construction of BVHs, Octrees, // and k-d Trees" -ByteAddressBuffer primitiveCounterBuffer : register(t0); +StructuredBuffer primitiveCounterBuffer : register(t0); StructuredBuffer primitiveIDBuffer : register(t1); StructuredBuffer primitiveMortonBuffer : register(t2); // float because it was sorted @@ -101,7 +101,7 @@ int FindSplit(int first, uint last, uint elementCount) void main( uint3 DTid : SV_DispatchThreadID ) { const uint idx = DTid.x; - const uint primitiveCount = primitiveCounterBuffer.Load(0); + const uint primitiveCount = primitiveCounterBuffer[0]; if (idx < primitiveCount - 1) { diff --git a/WickedEngine/shaders/bvh_propagateaabbCS.hlsl b/WickedEngine/shaders/bvh_propagateaabbCS.hlsl index 39fa2fcdc..30366dc67 100644 --- a/WickedEngine/shaders/bvh_propagateaabbCS.hlsl +++ b/WickedEngine/shaders/bvh_propagateaabbCS.hlsl @@ -7,7 +7,7 @@ // Parent node will merge child AABBs and store // Loop until we reach the root... -ByteAddressBuffer primitiveCounterBuffer : register(t0); +StructuredBuffer primitiveCounterBuffer : register(t0); StructuredBuffer primitiveIDBuffer : register(t1); ByteAddressBuffer primitiveBuffer : register(t2); StructuredBuffer bvhParentBuffer : register(t3); @@ -18,7 +18,7 @@ RWStructuredBuffer bvhFlagBuffer : register(u1); [numthreads(BVH_BUILDER_GROUPSIZE, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - const uint primitiveCount = primitiveCounterBuffer.Load(0); + const uint primitiveCount = primitiveCounterBuffer[0]; if (DTid.x < primitiveCount) { diff --git a/WickedEngine/shaders/emittedparticleMS.hlsl b/WickedEngine/shaders/emittedparticleMS.hlsl index b4ee31775..01698701e 100644 --- a/WickedEngine/shaders/emittedparticleMS.hlsl +++ b/WickedEngine/shaders/emittedparticleMS.hlsl @@ -10,7 +10,7 @@ static const float3 BILLBOARD[] = { }; static const uint BILLBOARD_VERTEXCOUNT = 4; -ByteAddressBuffer counterBuffer : register(t0); +StructuredBuffer counterBuffer : register(t0); StructuredBuffer particleBuffer : register(t1); StructuredBuffer culledIndirectionBuffer : register(t2); StructuredBuffer culledIndirectionBuffer2 : register(t3); @@ -43,7 +43,7 @@ void main( out primitives VertextoPixel_MS_PRIM sharedPrimitives[PRIMITIVECOUNT], out indices uint3 triangles[PRIMITIVECOUNT]) { - uint particleCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_CULLEDCOUNT); + uint particleCount = counterBuffer[0].culledCount; uint realGroupCount = min(THREADCOUNT_MESH_SHADER, particleCount - gid * THREADCOUNT_MESH_SHADER); // Set number of outputs diff --git a/WickedEngine/shaders/emittedparticle_emitCS.hlsl b/WickedEngine/shaders/emittedparticle_emitCS.hlsl index e34461b9d..d7c97551b 100644 --- a/WickedEngine/shaders/emittedparticle_emitCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_emitCS.hlsl @@ -15,7 +15,7 @@ RWStructuredBuffer particleBuffer : register(u0); RWStructuredBuffer aliveBuffer_CURRENT : register(u1); RWStructuredBuffer aliveBuffer_NEW : register(u2); RWStructuredBuffer deadBuffer : register(u3); -RWByteAddressBuffer counterBuffer : register(u4); +RWStructuredBuffer counterBuffer : register(u4); [numthreads(64, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) @@ -187,7 +187,7 @@ void main(uint3 DTid : SV_DispatchThreadID) // new particle index retrieved from dead list (pop): int deadCount; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, -1, deadCount); + InterlockedAdd(counterBuffer[0].deadCount, -1, deadCount); if(deadCount < 1) return; @@ -198,6 +198,6 @@ void main(uint3 DTid : SV_DispatchThreadID) // and add index to the alive list (push): uint aliveCount; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION, 1, aliveCount); + InterlockedAdd(counterBuffer[0].aliveCount_afterSimulation, 1, aliveCount); aliveBuffer_CURRENT[aliveCount] = newParticleIndex; } diff --git a/WickedEngine/shaders/emittedparticle_finishUpdateCS.hlsl b/WickedEngine/shaders/emittedparticle_finishUpdateCS.hlsl index 0a96517d8..baba860ec 100644 --- a/WickedEngine/shaders/emittedparticle_finishUpdateCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_finishUpdateCS.hlsl @@ -1,14 +1,14 @@ #include "globals.hlsli" #include "ShaderInterop_EmittedParticle.h" -ByteAddressBuffer counterBuffer : register(t0); +StructuredBuffer counterBuffer : register(t0); RWStructuredBuffer indirectBuffer : register(u0); [numthreads(1, 1, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { - uint particleCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_CULLEDCOUNT); + uint particleCount = counterBuffer[0].culledCount; if (xEmitterOptions & EMITTER_OPTION_BIT_MESH_SHADER_ENABLED) { diff --git a/WickedEngine/shaders/emittedparticle_kickoffUpdateCS.hlsl b/WickedEngine/shaders/emittedparticle_kickoffUpdateCS.hlsl index f68b02ca5..edc64c4f5 100644 --- a/WickedEngine/shaders/emittedparticle_kickoffUpdateCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_kickoffUpdateCS.hlsl @@ -1,14 +1,14 @@ #include "globals.hlsli" #include "ShaderInterop_EmittedParticle.h" -RWByteAddressBuffer counterBuffer : register(u4); +RWStructuredBuffer counterBuffer : register(u4); RWStructuredBuffer indirectBuffer : register(u5); [numthreads(1, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION); - int deadCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_DEADCOUNT); + uint aliveCount = counterBuffer[0].aliveCount_afterSimulation; + int deadCount = counterBuffer[0].deadCount; IndirectDispatchArgs args; args.ThreadGroupCountX = (aliveCount + THREADCOUNT_SIMULATION - 1) / THREADCOUNT_SIMULATION; @@ -16,12 +16,12 @@ void main(uint3 DTid : SV_DispatchThreadID) args.ThreadGroupCountZ = 1; indirectBuffer[0].dispatch = args; - counterBuffer.Store(PARTICLECOUNTER_OFFSET_ALIVECOUNT, aliveCount); - counterBuffer.Store(PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION, 0); + counterBuffer[0].aliveCount = aliveCount; + counterBuffer[0].aliveCount_afterSimulation = 0; - counterBuffer.Store(PARTICLECOUNTER_OFFSET_DEADCOUNT, max(0, deadCount)); + counterBuffer[0].deadCount = max(0, deadCount); - counterBuffer.Store(PARTICLECOUNTER_OFFSET_CULLEDCOUNT, 0); + counterBuffer[0].culledCount = 0; - counterBuffer.Store(PARTICLECOUNTER_OFFSET_CELLALLOCATOR, 0); + counterBuffer[0].cellAllocator = 0; } diff --git a/WickedEngine/shaders/emittedparticle_simulateCS.hlsl b/WickedEngine/shaders/emittedparticle_simulateCS.hlsl index c540c0c36..ec3d703c3 100644 --- a/WickedEngine/shaders/emittedparticle_simulateCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_simulateCS.hlsl @@ -16,7 +16,7 @@ RWStructuredBuffer particleBuffer : register(u0); RWStructuredBuffer aliveBuffer_CURRENT : register(u1); RWStructuredBuffer aliveBuffer_NEW : register(u2); RWStructuredBuffer deadBuffer : register(u3); -RWByteAddressBuffer counterBuffer : register(u4); +RWStructuredBuffer counterBuffer : register(u4); RWStructuredBuffer distanceBuffer : register(u6); RWBuffer vertexBuffer_POS : register(u7); RWBuffer vertexBuffer_NOR : register(u8); @@ -32,7 +32,7 @@ RWStructuredBuffer culledIndirectionBuffer2 : register(u12); [numthreads(THREADCOUNT_SIMULATION, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) { - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT); + uint aliveCount = counterBuffer[0].aliveCount; if (DTid.x >= aliveCount) return; @@ -272,7 +272,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) // add to new alive list: uint newAliveIndex; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT_AFTERSIMULATION, 1, newAliveIndex); + InterlockedAdd(counterBuffer[0].aliveCount_afterSimulation, 1, newAliveIndex); aliveBuffer_NEW[newAliveIndex] = particleIndex; // Write out render buffers: @@ -339,7 +339,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) if (GetCamera().frustum.intersects(sphere)) { uint prevCount; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_CULLEDCOUNT, 1, prevCount); + InterlockedAdd(counterBuffer[0].culledCount, 1, prevCount); culledIndirectionBuffer[prevCount] = prevCount; culledIndirectionBuffer2[prevCount] = particleIndex; @@ -357,7 +357,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) { // kill: uint deadIndex; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, 1, deadIndex); + InterlockedAdd(counterBuffer[0].deadCount, 1, deadIndex); deadBuffer[deadIndex] = particleIndex; vertexBuffer_POS[v0 + 0] = 0; diff --git a/WickedEngine/shaders/emittedparticle_sphbinningCS.hlsl b/WickedEngine/shaders/emittedparticle_sphbinningCS.hlsl index 09d4ae161..3a0bbc018 100644 --- a/WickedEngine/shaders/emittedparticle_sphbinningCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_sphbinningCS.hlsl @@ -4,14 +4,14 @@ StructuredBuffer aliveBuffer_CURRENT : register(t0); StructuredBuffer particleBuffer : register(t1); -RWByteAddressBuffer counterBuffer : register(u0); +RWStructuredBuffer counterBuffer : register(u0); RWStructuredBuffer cellBuffer : register(u1); RWStructuredBuffer particleCellBuffer : register(u2); [numthreads(THREADCOUNT_SIMULATION, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT); + uint aliveCount = counterBuffer[0].aliveCount; if (DTid.x >= aliveCount) return; diff --git a/WickedEngine/shaders/emittedparticle_sphcellallocationCS.hlsl b/WickedEngine/shaders/emittedparticle_sphcellallocationCS.hlsl index 89576657a..33c9526a8 100644 --- a/WickedEngine/shaders/emittedparticle_sphcellallocationCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_sphcellallocationCS.hlsl @@ -4,7 +4,7 @@ StructuredBuffer aliveBuffer_CURRENT : register(t0); StructuredBuffer particleBuffer : register(t1); -RWByteAddressBuffer counterBuffer : register(u0); +RWStructuredBuffer counterBuffer : register(u0); RWStructuredBuffer cellBuffer : register(u1); [numthreads(THREADCOUNT_SIMULATION, 1, 1)] @@ -12,6 +12,6 @@ void main(uint3 DTid : SV_DispatchThreadID) { if (cellBuffer[DTid.x].count == 0) return; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_CELLALLOCATOR, cellBuffer[DTid.x].count, cellBuffer[DTid.x].offset); + InterlockedAdd(counterBuffer[0].cellAllocator, cellBuffer[DTid.x].count, cellBuffer[DTid.x].offset); cellBuffer[DTid.x].count = 0; // will be reused for binning } diff --git a/WickedEngine/shaders/emittedparticle_sphdensityCS.hlsl b/WickedEngine/shaders/emittedparticle_sphdensityCS.hlsl index 5bfb76276..52ba6f43f 100644 --- a/WickedEngine/shaders/emittedparticle_sphdensityCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_sphdensityCS.hlsl @@ -6,7 +6,7 @@ StructuredBuffer particleBuffer : register(t1); StructuredBuffer particleCellBuffer : register(t2); StructuredBuffer cellBuffer : register(t3); -RWByteAddressBuffer counterBuffer : register(u0); +RWStructuredBuffer counterBuffer : register(u0); RWStructuredBuffer densityBuffer : register(u1); #ifndef SPH_USE_ACCELERATION_GRID @@ -25,7 +25,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, ui const float p0 = xSPH_p0; // reference density const float e = xSPH_e; // viscosity constant - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT); + uint aliveCount = counterBuffer[0].aliveCount; uint particleIndexA; float3 positionA; diff --git a/WickedEngine/shaders/emittedparticle_sphforceCS.hlsl b/WickedEngine/shaders/emittedparticle_sphforceCS.hlsl index c625acd91..d3af31e29 100644 --- a/WickedEngine/shaders/emittedparticle_sphforceCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_sphforceCS.hlsl @@ -8,7 +8,7 @@ StructuredBuffer densityBuffer : register(t1); StructuredBuffer particleCellBuffer : register(t2); StructuredBuffer cellBuffer : register(t3); -RWByteAddressBuffer counterBuffer : register(u0); +RWStructuredBuffer counterBuffer : register(u0); RWStructuredBuffer particleBuffer : register(u1); #ifndef SPH_USE_ACCELERATION_GRID @@ -29,7 +29,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, ui const float p0 = xSPH_p0; // reference density const float e = xSPH_e; // viscosity constant - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT); + uint aliveCount = counterBuffer[0].aliveCount; uint particleIndexA; Particle particleA; diff --git a/WickedEngine/shaders/emittedparticle_sphpartitionCS.hlsl b/WickedEngine/shaders/emittedparticle_sphpartitionCS.hlsl index 7578831f2..d3c875617 100644 --- a/WickedEngine/shaders/emittedparticle_sphpartitionCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_sphpartitionCS.hlsl @@ -4,13 +4,13 @@ StructuredBuffer aliveBuffer_CURRENT : register(t0); StructuredBuffer particleBuffer : register(t1); -RWByteAddressBuffer counterBuffer : register(u0); +RWStructuredBuffer counterBuffer : register(u0); RWStructuredBuffer cellBuffer : register(u1); [numthreads(THREADCOUNT_SIMULATION, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT); + uint aliveCount = counterBuffer[0].aliveCount; if (DTid.x >= aliveCount) return; diff --git a/WickedEngine/shaders/gpusortlib_kickoffSortCS.hlsl b/WickedEngine/shaders/gpusortlib_kickoffSortCS.hlsl index 27e1b4ccd..e4d2a4460 100644 --- a/WickedEngine/shaders/gpusortlib_kickoffSortCS.hlsl +++ b/WickedEngine/shaders/gpusortlib_kickoffSortCS.hlsl @@ -1,27 +1,28 @@ #include "globals.hlsli" #include "ShaderInterop_GPUSortLib.h" -ByteAddressBuffer counterBuffer : register(t0); - -RWByteAddressBuffer indirectBuffers : register(u0); +RWStructuredBuffer indirectBuffers : register(u0); [numthreads(1, 1, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { // retrieve GPU itemcount: - uint itemCount = counterBuffer.Load(sort.counterReadOffset); + uint itemCount = counterBuffer.count; + + IndirectDispatchArgs args; if (itemCount > 0) { - // calculate threadcount: - uint threadCount = ((itemCount - 1) >> 9) + 1; - - // and prepare to dispatch the sort for the alive simulated particles: - indirectBuffers.Store3(0, uint3(threadCount, 1, 1)); + args.ThreadGroupCountX = ((itemCount - 1) >> 9) + 1; + args.ThreadGroupCountY = 1; + args.ThreadGroupCountZ = 1; } else { - // dispatch nothing: - indirectBuffers.Store3(0, uint3(0, 0, 0)); + args.ThreadGroupCountX = 0; + args.ThreadGroupCountY = 0; + args.ThreadGroupCountZ = 0; } + + indirectBuffers[0] = args; } diff --git a/WickedEngine/shaders/gpusortlib_sortCS.hlsl b/WickedEngine/shaders/gpusortlib_sortCS.hlsl index a03e7b722..d59f697d0 100644 --- a/WickedEngine/shaders/gpusortlib_sortCS.hlsl +++ b/WickedEngine/shaders/gpusortlib_sortCS.hlsl @@ -40,8 +40,7 @@ //-------------------------------------------------------------------------------------- // Structured Buffers //-------------------------------------------------------------------------------------- -ByteAddressBuffer counterBuffer : register(t0); -StructuredBuffer comparisonBuffer : register(t1); +StructuredBuffer comparisonBuffer : register(t0); RWStructuredBuffer indexBuffer : register(u0); @@ -58,7 +57,7 @@ void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex) { - uint NumElements = counterBuffer.Load(sort.counterReadOffset); + uint NumElements = counterBuffer.count; uint GlobalBaseIndex = (Gid.x * SORT_SIZE) + GTid.x; uint LocalBaseIndex = GI; diff --git a/WickedEngine/shaders/gpusortlib_sortInnerCS.hlsl b/WickedEngine/shaders/gpusortlib_sortInnerCS.hlsl index a4b876dbf..a8edb1c8b 100644 --- a/WickedEngine/shaders/gpusortlib_sortInnerCS.hlsl +++ b/WickedEngine/shaders/gpusortlib_sortInnerCS.hlsl @@ -32,28 +32,19 @@ #define NUM_THREADS (SORT_SIZE/2) #define INVERSION (16*2 + 8*3) -//-------------------------------------------------------------------------------------- -// Structured Buffers -//-------------------------------------------------------------------------------------- -ByteAddressBuffer counterBuffer : register(t0); -StructuredBuffer comparisonBuffer : register(t1); +StructuredBuffer comparisonBuffer : register(t0); RWStructuredBuffer indexBuffer : register(u0); - -//-------------------------------------------------------------------------------------- -// Bitonic Sort Compute Shader -//-------------------------------------------------------------------------------------- groupshared float2 g_LDS[SORT_SIZE]; - [numthreads(NUM_THREADS, 1, 1)] void main(uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex) { - uint NumElements = counterBuffer.Load(sort.counterReadOffset); + uint NumElements = counterBuffer.count; uint4 tgp; diff --git a/WickedEngine/shaders/gpusortlib_sortStepCS.hlsl b/WickedEngine/shaders/gpusortlib_sortStepCS.hlsl index ffae6c127..39573434b 100644 --- a/WickedEngine/shaders/gpusortlib_sortStepCS.hlsl +++ b/WickedEngine/shaders/gpusortlib_sortStepCS.hlsl @@ -23,11 +23,9 @@ #include "globals.hlsli" #include "ShaderInterop_GPUSortLib.h" -//-------------------------------------------------------------------------------------- -// Structured Buffers -//-------------------------------------------------------------------------------------- -ByteAddressBuffer counterBuffer : register(t0); -StructuredBuffer comparisonBuffer : register(t1); +PUSHCONSTANT(sort, SortConstants); + +StructuredBuffer comparisonBuffer : register(t0); RWStructuredBuffer indexBuffer : register(u0); @@ -35,7 +33,7 @@ RWStructuredBuffer indexBuffer : register(u0); void main(uint3 Gid : SV_GroupID, uint3 GTid : SV_GroupThreadID) { - uint NumElements = counterBuffer.Load(sort.counterReadOffset); + uint NumElements = counterBuffer.count; uint4 tgp; diff --git a/WickedEngine/shaders/raytracingHF.hlsli b/WickedEngine/shaders/raytracingHF.hlsli index 685c6bf72..7179e0d83 100644 --- a/WickedEngine/shaders/raytracingHF.hlsli +++ b/WickedEngine/shaders/raytracingHF.hlsli @@ -94,7 +94,7 @@ void ray_clip_plane(inout RayDesc ray, float4 clip_plane) groupshared uint stack[RAYTRACE_STACKSIZE][8 * 4]; #endif // RAYTRACE_STACK_SHARED -#define primitiveCounterBuffer bindless_buffers[descriptor_index(GetScene().BVH_counter)] +#define primitiveCounterBuffer bindless_structured_uint[descriptor_index(GetScene().BVH_counter)] #define bvhNodeBuffer bindless_buffers[descriptor_index(GetScene().BVH_nodes)] #define primitiveBuffer bindless_buffers[descriptor_index(GetScene().BVH_primitives)] @@ -291,7 +291,7 @@ inline RayHit TraceRay_Closest(RayDesc ray, uint mask, inout RNG rng, uint group #endif // RAYTRACE_STACK_SHARED uint stackpos = 0; - const uint primitiveCount = primitiveCounterBuffer.Load(0); + const uint primitiveCount = primitiveCounterBuffer[0]; const uint leafNodeOffset = primitiveCount - 1; // push root node @@ -352,8 +352,8 @@ inline bool TraceRay_Any(RayDesc ray, uint mask, inout RNG rng, uint groupIndex uint stack[RAYTRACE_STACKSIZE][1]; #endif // RAYTRACE_STACK_SHARED uint stackpos = 0; - - const uint primitiveCount = primitiveCounterBuffer.Load(0); + + const uint primitiveCount = primitiveCounterBuffer[0]; const uint leafNodeOffset = primitiveCount - 1; // push root node @@ -417,8 +417,8 @@ inline uint TraceRay_DebugBVH(RayDesc ray) // Emulated stack for tree traversal: uint stack[RAYTRACE_STACKSIZE]; uint stackpos = 0; - - const uint primitiveCount = primitiveCounterBuffer.Load(0); + + const uint primitiveCount = primitiveCounterBuffer[0]; const uint leafNodeOffset = primitiveCount - 1; // push root node diff --git a/WickedEngine/shaders/surfel_binningCS.hlsl b/WickedEngine/shaders/surfel_binningCS.hlsl index b711a6466..0b85f7059 100644 --- a/WickedEngine/shaders/surfel_binningCS.hlsl +++ b/WickedEngine/shaders/surfel_binningCS.hlsl @@ -3,7 +3,7 @@ StructuredBuffer surfelBuffer : register(t0); StructuredBuffer surfelAliveBuffer : register(t1); -ByteAddressBuffer surfelStatsBuffer : register(t2); +StructuredBuffer surfelStatsBuffer : register(t2); RWStructuredBuffer surfelGridBuffer : register(u0); RWStructuredBuffer surfelCellBuffer : register(u1); @@ -11,7 +11,7 @@ RWStructuredBuffer surfelCellBuffer : register(u1); [numthreads(SURFEL_INDIRECT_NUMTHREADS, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint surfel_count = surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_COUNT); + uint surfel_count = surfelStatsBuffer[0].count; if (DTid.x >= surfel_count) return; diff --git a/WickedEngine/shaders/surfel_coverageCS.hlsl b/WickedEngine/shaders/surfel_coverageCS.hlsl index 37e4f1ff2..b3624052a 100644 --- a/WickedEngine/shaders/surfel_coverageCS.hlsl +++ b/WickedEngine/shaders/surfel_coverageCS.hlsl @@ -14,7 +14,7 @@ Texture2D surfelMomentsTexture : register(t3); RWStructuredBuffer surfelDataBuffer : register(u0); RWStructuredBuffer surfelDeadBuffer : register(u1); RWStructuredBuffer surfelAliveBuffer : register(u2); -RWByteAddressBuffer surfelStatsBuffer : register(u3); +RWStructuredBuffer surfelStatsBuffer : register(u3); RWTexture2D result : register(u4); RWTexture2D debugUAV : register(u5); @@ -237,14 +237,14 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uin // new particle index retrieved from dead list (pop): int deadCount; - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_DEADCOUNT, -1, deadCount); + InterlockedAdd(surfelStatsBuffer[0].deadCount, -1, deadCount); if (deadCount <= 0 || deadCount > SURFEL_CAPACITY) return; uint newSurfelIndex = surfelDeadBuffer[deadCount - 1]; // and add index to the alive list (push): uint aliveCount; - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_NEXTCOUNT, 1, aliveCount); + InterlockedAdd(surfelStatsBuffer[0].nextCount, 1, aliveCount); if (aliveCount < SURFEL_CAPACITY) { surfelAliveBuffer[aliveCount] = newSurfelIndex; diff --git a/WickedEngine/shaders/surfel_gridoffsetsCS.hlsl b/WickedEngine/shaders/surfel_gridoffsetsCS.hlsl index f44c743d2..cd7440393 100644 --- a/WickedEngine/shaders/surfel_gridoffsetsCS.hlsl +++ b/WickedEngine/shaders/surfel_gridoffsetsCS.hlsl @@ -3,13 +3,13 @@ RWStructuredBuffer surfelGridBuffer : register(u0); RWStructuredBuffer surfelCellBuffer : register(u1); -RWByteAddressBuffer surfelStatsBuffer : register(u2); +RWStructuredBuffer surfelStatsBuffer : register(u2); [numthreads(64, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { if (surfelGridBuffer[DTid.x].count == 0) return; - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_CELLALLOCATOR, surfelGridBuffer[DTid.x].count, surfelGridBuffer[DTid.x].offset); + InterlockedAdd(surfelStatsBuffer[0].cellAllocator, surfelGridBuffer[DTid.x].count, surfelGridBuffer[DTid.x].offset); surfelGridBuffer[DTid.x].count = 0; } diff --git a/WickedEngine/shaders/surfel_indirectprepareCS.hlsl b/WickedEngine/shaders/surfel_indirectprepareCS.hlsl index d13c82cc5..726d9f453 100644 --- a/WickedEngine/shaders/surfel_indirectprepareCS.hlsl +++ b/WickedEngine/shaders/surfel_indirectprepareCS.hlsl @@ -1,27 +1,27 @@ #include "globals.hlsli" #include "ShaderInterop_SurfelGI.h" -RWByteAddressBuffer surfelStatsBuffer : register(u0); +RWStructuredBuffer surfelStatsBuffer : register(u0); RWStructuredBuffer surfelIndirectBuffer : register(u1); [numthreads(1, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint surfel_count = surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_NEXTCOUNT); + uint surfel_count = surfelStatsBuffer[0].nextCount; surfel_count = clamp(surfel_count, 0, SURFEL_CAPACITY); - int dead_count = asint(surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_DEADCOUNT)); + int dead_count = surfelStatsBuffer[0].deadCount; int shortage = max(0, -dead_count); // if deadcount was negative, there was shortage dead_count = clamp(dead_count, 0, (int)SURFEL_CAPACITY); - uint ray_count = surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_RAYCOUNT); + uint ray_count = surfelStatsBuffer[0].rayCount; - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_COUNT, surfel_count); - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_NEXTCOUNT, 0); - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_DEADCOUNT, dead_count); - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_CELLALLOCATOR, 0); - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_RAYCOUNT, 0); - surfelStatsBuffer.Store(SURFEL_STATS_OFFSET_SHORTAGE, shortage); + surfelStatsBuffer[0].count = surfel_count; + surfelStatsBuffer[0].nextCount = 0; + surfelStatsBuffer[0].deadCount = dead_count; + surfelStatsBuffer[0].cellAllocator = 0; + surfelStatsBuffer[0].rayCount = 0; + surfelStatsBuffer[0].shortage = shortage; SurfelIndirectArgs args; diff --git a/WickedEngine/shaders/surfel_raytraceCS.hlsl b/WickedEngine/shaders/surfel_raytraceCS.hlsl index 715c8081e..17a175908 100644 --- a/WickedEngine/shaders/surfel_raytraceCS.hlsl +++ b/WickedEngine/shaders/surfel_raytraceCS.hlsl @@ -7,7 +7,7 @@ PUSHCONSTANT(push, PushConstantsSurfelRaytrace); StructuredBuffer surfelBuffer : register(t0); -ByteAddressBuffer surfelStatsBuffer : register(t1); +StructuredBuffer surfelStatsBuffer : register(t1); StructuredBuffer surfelGridBuffer : register(t2); StructuredBuffer surfelCellBuffer : register(t3); StructuredBuffer surfelAliveBuffer : register(t4); @@ -18,7 +18,7 @@ RWStructuredBuffer surfelRayBuffer : register(u0); [numthreads(SURFEL_INDIRECT_NUMTHREADS, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint global_ray_count = surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_RAYCOUNT); + uint global_ray_count = surfelStatsBuffer[0].rayCount; if (DTid.x >= global_ray_count) return; diff --git a/WickedEngine/shaders/surfel_updateCS.hlsl b/WickedEngine/shaders/surfel_updateCS.hlsl index 2281dfe6f..750e6b98c 100644 --- a/WickedEngine/shaders/surfel_updateCS.hlsl +++ b/WickedEngine/shaders/surfel_updateCS.hlsl @@ -9,14 +9,14 @@ RWStructuredBuffer surfelBuffer : register(u0); RWStructuredBuffer surfelGridBuffer : register(u1); RWStructuredBuffer surfelAliveBuffer_NEXT : register(u2); RWStructuredBuffer surfelDeadBuffer : register(u3); -RWByteAddressBuffer surfelStatsBuffer : register(u4); +RWStructuredBuffer surfelStatsBuffer : register(u4); RWStructuredBuffer surfelRayBuffer : register(u5); RWStructuredBuffer surfelDataBuffer : register(u6); [numthreads(SURFEL_INDIRECT_NUMTHREADS, 1, 1)] void main(uint3 DTid : SV_DispatchThreadID) { - uint surfel_count = surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_COUNT); + uint surfel_count = surfelStatsBuffer[0].count; if (DTid.x >= surfel_count) return; @@ -60,7 +60,7 @@ void main(uint3 DTid : SV_DispatchThreadID) } bool shortage = true; - shortage = asint(surfelStatsBuffer.Load(SURFEL_STATS_OFFSET_SHORTAGE)) > 0; + shortage = surfelStatsBuffer[0].shortage > 0; if (surfel_data.GetRecycle() > SURFEL_RECYCLE_TIME && shortage) { radius = 0; @@ -69,7 +69,7 @@ void main(uint3 DTid : SV_DispatchThreadID) if (radius > 0) { uint aliveCount; - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_NEXTCOUNT, 1, aliveCount); + InterlockedAdd(surfelStatsBuffer[0].nextCount, 1, aliveCount); surfelAliveBuffer_NEXT[aliveCount] = surfel_index; // Determine ray count for surfel: @@ -86,7 +86,7 @@ void main(uint3 DTid : SV_DispatchThreadID) uint rayOffset = 0; if (rayCountRequest > 0) { - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_RAYCOUNT, rayCountRequest, rayOffset); + InterlockedAdd(surfelStatsBuffer[0].rayCount, rayCountRequest, rayOffset); } uint rayCount = (rayOffset < SURFEL_RAY_BUDGET) ? rayCountRequest : 0; rayCount = clamp(rayCount, 0, SURFEL_RAY_BUDGET - rayOffset); @@ -111,7 +111,7 @@ void main(uint3 DTid : SV_DispatchThreadID) else { int deadCount; - surfelStatsBuffer.InterlockedAdd(SURFEL_STATS_OFFSET_DEADCOUNT, 1, deadCount); + InterlockedAdd(surfelStatsBuffer[0].deadCount, 1, deadCount); surfelDeadBuffer[deadCount] = surfel_index; } } diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index 9abc0b320..8cc1172f9 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -227,8 +227,9 @@ namespace wi GPUBufferDesc bd; bd.usage = Usage::DEFAULT; bd.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS; - bd.size = sizeof(counters); - bd.misc_flags = ResourceMiscFlag::BUFFER_RAW; + bd.stride = sizeof(counters); + bd.size = bd.stride; + bd.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; device->CreateBuffer(&bd, &counters, &counterBuffer); device->SetName(&counterBuffer, "EmittedParticleSystem::counterBuffer"); } @@ -773,7 +774,7 @@ namespace wi if (IsSorted()) { - wi::gpusortlib::Sort(MAX_PARTICLES, distanceBuffer, counterBuffer, PARTICLECOUNTER_OFFSET_CULLEDCOUNT, culledIndirectionBuffer, cmd); + wi::gpusortlib::Sort(MAX_PARTICLES, distanceBuffer, counterBuffer, offsetof(ParticleCounters, culledCount), culledIndirectionBuffer, cmd); } if (!IsPaused() && dt > 0) @@ -816,7 +817,7 @@ namespace wi // Statistics is copied to readback: const uint32_t oldest_stat_index = wi::graphics::GetDevice()->GetBufferIndex(); - device->CopyResource(&statisticsReadbackBuffer[oldest_stat_index], &counterBuffer, cmd); + device->CopyBuffer(&statisticsReadbackBuffer[oldest_stat_index], 0, &counterBuffer, 0, sizeof(ParticleCounters), cmd); { const GPUBarrier barriers[] = { diff --git a/WickedEngine/wiGPUBVH.cpp b/WickedEngine/wiGPUBVH.cpp index 9bc7f6c08..c11a39b38 100644 --- a/WickedEngine/wiGPUBVH.cpp +++ b/WickedEngine/wiGPUBVH.cpp @@ -66,7 +66,7 @@ namespace wi desc.bind_flags = BindFlag::SHADER_RESOURCE; desc.stride = sizeof(uint); desc.size = desc.stride; - desc.misc_flags = ResourceMiscFlag::BUFFER_RAW; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; desc.usage = Usage::DEFAULT; device->CreateBuffer(&desc, nullptr, &primitiveCounterBuffer); device->SetName(&primitiveCounterBuffer, "GPUBVH::primitiveCounterBuffer"); @@ -232,15 +232,13 @@ namespace wi ); } } - - GPUBarrier barriers[] = { - GPUBarrier::Memory() - }; - device->Barrier(barriers, arraysize(barriers), cmd); } { GPUBarrier barriers[] = { + GPUBarrier::Buffer(&primitiveBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), + GPUBarrier::Buffer(&primitiveIDBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), + GPUBarrier::Buffer(&primitiveMortonBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), GPUBarrier::Buffer(&primitiveCounterBuffer, ResourceState::SHADER_RESOURCE, ResourceState::COPY_DST), }; device->Barrier(barriers, arraysize(barriers), cmd); @@ -278,20 +276,20 @@ namespace wi device->Dispatch((primitiveCount + BVH_BUILDER_GROUPSIZE - 1) / BVH_BUILDER_GROUPSIZE, 1, 1, cmd); - GPUBarrier barriers[] = { - GPUBarrier::Memory() - }; - device->Barrier(barriers, arraysize(barriers), cmd); } device->EventEnd(cmd); - device->EventBegin("BVH - Propagate AABB", cmd); { GPUBarrier barriers[] = { - GPUBarrier::Memory() + GPUBarrier::Memory(&bvhNodeBuffer), + GPUBarrier::Memory(&bvhFlagBuffer), + GPUBarrier::Buffer(&bvhParentBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), }; device->Barrier(barriers, arraysize(barriers), cmd); + } + device->EventBegin("BVH - Propagate AABB", cmd); + { device->BindComputeShader(&computeShaders[CSTYPE_BVH_PROPAGATEAABB], cmd); const GPUResource* uavs[] = { &bvhNodeBuffer, @@ -309,10 +307,17 @@ namespace wi device->Dispatch((primitiveCount + BVH_BUILDER_GROUPSIZE - 1) / BVH_BUILDER_GROUPSIZE, 1, 1, cmd); - device->Barrier(barriers, arraysize(barriers), cmd); } device->EventEnd(cmd); + { + GPUBarrier barriers[] = { + GPUBarrier::Buffer(&bvhNodeBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), + GPUBarrier::Buffer(&bvhFlagBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + } + wi::profiler::EndRange(range); // BVH rebuild #ifdef BVH_VALIDATE diff --git a/WickedEngine/wiGPUSortLib.cpp b/WickedEngine/wiGPUSortLib.cpp index 8a5b79c04..fe99ebad9 100644 --- a/WickedEngine/wiGPUSortLib.cpp +++ b/WickedEngine/wiGPUSortLib.cpp @@ -10,20 +10,19 @@ using namespace wi::graphics; namespace wi::gpusortlib { + static GPUBuffer constantBuffer; static GPUBuffer indirectBuffer; static Shader kickoffSortCS; static Shader sortCS; static Shader sortInnerCS; static Shader sortStepCS; - void LoadShaders() { wi::renderer::LoadShader(ShaderStage::CS, kickoffSortCS, "gpusortlib_kickoffSortCS.cso"); wi::renderer::LoadShader(ShaderStage::CS, sortCS, "gpusortlib_sortCS.cso"); wi::renderer::LoadShader(ShaderStage::CS, sortInnerCS, "gpusortlib_sortInnerCS.cso"); wi::renderer::LoadShader(ShaderStage::CS, sortStepCS, "gpusortlib_sortStepCS.cso"); - } void Initialize() @@ -32,9 +31,15 @@ namespace wi::gpusortlib GPUBufferDesc bd; bd.usage = Usage::DEFAULT; + + bd.bind_flags = BindFlag::CONSTANT_BUFFER; + bd.size = sizeof(SortCount); + wi::graphics::GetDevice()->CreateBuffer(&bd, nullptr, &constantBuffer); + bd.bind_flags = BindFlag::UNORDERED_ACCESS; - bd.misc_flags = ResourceMiscFlag::INDIRECT_ARGS | ResourceMiscFlag::BUFFER_RAW; - bd.size = sizeof(IndirectDispatchArgs); + bd.misc_flags = ResourceMiscFlag::INDIRECT_ARGS | ResourceMiscFlag::BUFFER_STRUCTURED; + bd.stride = sizeof(IndirectDispatchArgs); + bd.size = bd.stride; wi::graphics::GetDevice()->CreateBuffer(&bd, nullptr, &indirectBuffer); static wi::eventhandler::Handle handle = wi::eventhandler::Subscribe(wi::eventhandler::EVENT_RELOAD_SHADERS, [](uint64_t userdata) { LoadShaders(); }); @@ -47,8 +52,8 @@ namespace wi::gpusortlib void Sort( uint32_t maxCount, const GPUBuffer& comparisonBuffer_read, - const GPUBuffer& counterBuffer_read, - uint32_t counterReadOffset, + const GPUBuffer& counterBuffer_read, + uint counterReadOffset, const GPUBuffer& indexBuffer_write, CommandList cmd) { @@ -56,52 +61,49 @@ namespace wi::gpusortlib device->EventBegin("GPUSortLib", cmd); + // init count constant buffer from source buffer and offset: + { + { + GPUBarrier barriers[] = { + GPUBarrier::Buffer(&counterBuffer_read, ResourceState::SHADER_RESOURCE, ResourceState::COPY_SRC), + GPUBarrier::Buffer(&constantBuffer, ResourceState::CONSTANT_BUFFER, ResourceState::COPY_DST), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + } + device->CopyBuffer(&constantBuffer, offsetof(SortCount, count), &counterBuffer_read, counterReadOffset, sizeof(SortCount::count), cmd); + { + GPUBarrier barriers[] = { + GPUBarrier::Buffer(&counterBuffer_read, ResourceState::COPY_SRC, ResourceState::SHADER_RESOURCE), + GPUBarrier::Buffer(&constantBuffer, ResourceState::COPY_DST, ResourceState::CONSTANT_BUFFER), + }; + device->Barrier(barriers, arraysize(barriers), cmd); + } - SortConstants sort; - sort.counterReadOffset = counterReadOffset; + device->BindConstantBuffer(&constantBuffer, CBSLOT_GPUSORTLIB, cmd); + } // initialize sorting arguments: { device->BindComputeShader(&kickoffSortCS, cmd); - const GPUResource* res[] = { - &counterBuffer_read, - }; - device->BindResources(res, 0, arraysize(res), cmd); - const GPUResource* uavs[] = { &indirectBuffer, }; device->BindUAVs(uavs, 0, arraysize(uavs), cmd); - { - GPUBarrier barriers[] = { - GPUBarrier::Buffer(&indirectBuffer, ResourceState::INDIRECT_ARGUMENT, ResourceState::UNORDERED_ACCESS) - }; - device->Barrier(barriers, arraysize(barriers), cmd); - } + device->Barrier(GPUBarrier::Buffer(&indirectBuffer, ResourceState::INDIRECT_ARGUMENT, ResourceState::UNORDERED_ACCESS), cmd); - device->PushConstants(&sort, sizeof(sort), cmd); device->Dispatch(1, 1, 1, cmd); - { - GPUBarrier barriers[] = { - GPUBarrier::Memory(), - GPUBarrier::Buffer(&indirectBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::INDIRECT_ARGUMENT) - }; - device->Barrier(barriers, arraysize(barriers), cmd); - } - + device->Barrier(GPUBarrier::Buffer(&indirectBuffer, ResourceState::UNORDERED_ACCESS, ResourceState::INDIRECT_ARGUMENT), cmd); } - const GPUResource* uavs[] = { &indexBuffer_write, }; device->BindUAVs(uavs, 0, arraysize(uavs), cmd); const GPUResource* resources[] = { - &counterBuffer_read, &comparisonBuffer_read, }; device->BindResources(resources, 0, arraysize(resources), cmd); @@ -125,13 +127,10 @@ namespace wi::gpusortlib // sort all buffers of size 512 (and presort bigger ones) device->BindComputeShader(&sortCS, cmd); - device->PushConstants(&sort, sizeof(sort), cmd); + device->DispatchIndirect(&indirectBuffer, 0, cmd); - GPUBarrier barriers[] = { - GPUBarrier::Memory(), - }; - device->Barrier(barriers, arraysize(barriers), cmd); + device->Barrier(GPUBarrier::Memory(), cmd); } int presorted = 512; @@ -171,7 +170,6 @@ namespace wi::gpusortlib sort.job_params.y = nMergeSubSize; sort.job_params.z = 1; } - sort.counterReadOffset = counterReadOffset; device->PushConstants(&sort, sizeof(sort), cmd); device->Dispatch(numThreadGroups, 1, 1, cmd); @@ -183,7 +181,6 @@ namespace wi::gpusortlib } device->BindComputeShader(&sortInnerCS, cmd); - device->PushConstants(&sort, sizeof(sort), cmd); device->Dispatch(numThreadGroups, 1, 1, cmd); GPUBarrier barriers[] = { diff --git a/WickedEngine/wiGPUSortLib.h b/WickedEngine/wiGPUSortLib.h index 96954dda6..f3d8d7c38 100644 --- a/WickedEngine/wiGPUSortLib.h +++ b/WickedEngine/wiGPUSortLib.h @@ -11,10 +11,10 @@ namespace wi::gpusortlib // counterReadOffset - Byte offset into the counter buffer to read the count value (Read Only) // indexBuffer_write - The index list which to sort. Contains index values which can index the sortBase_read buffer. This will be modified (Read + Write) void Sort( - uint32_t maxCount, - const wi::graphics::GPUBuffer& comparisonBuffer_read, - const wi::graphics::GPUBuffer& counterBuffer_read, - uint32_t counterReadOffset, + uint32_t maxCount, + const wi::graphics::GPUBuffer& comparisonBuffer_read, + const wi::graphics::GPUBuffer& counterBuffer_read, + uint32_t counterReadOffset, const wi::graphics::GPUBuffer& indexBuffer_write, wi::graphics::CommandList cmd ); diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index ba724ddaa..37c46d538 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -3544,7 +3544,7 @@ std::mutex queue_locker; D3D12_RESOURCE_STATES resourceState = _ParseResourceState(texture->desc.layout); - if (initial_data != nullptr) + if (initial_data != nullptr || (resourcedesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS)) { resourceState = D3D12_RESOURCE_STATE_COMMON; } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index e87b9b883..c40a0bc21 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -10857,6 +10857,14 @@ void RayTraceScene( { PushBarrier(GPUBarrier::Image(output_primitiveID, ResourceState::UNORDERED_ACCESS, output_primitiveID->desc.layout)); } + if (output_depth != nullptr) + { + PushBarrier(GPUBarrier::Image(output_depth, ResourceState::UNORDERED_ACCESS, output_depth->desc.layout)); + } + if (output_stencil != nullptr) + { + PushBarrier(GPUBarrier::Image(output_stencil, ResourceState::UNORDERED_ACCESS, output_depth->desc.layout)); + } PushBarrier(GPUBarrier::Image(&output, ResourceState::UNORDERED_ACCESS, output.desc.layout)); FlushBarriers(cmd); @@ -12348,7 +12356,6 @@ void DDGI( GPUBarrier::Buffer(&scene.ddgi.ray_buffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE), GPUBarrier::Image(&scene.ddgi.depth_texture, ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS), GPUBarrier::Buffer(&scene.ddgi.variance_buffer, ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS), - GPUBarrier::Buffer(&scene.ddgi.raycount_buffer, ResourceState::UNORDERED_ACCESS, ResourceState::SHADER_RESOURCE_COMPUTE), GPUBarrier::Buffer(&scene.ddgi.probe_buffer, ResourceState::SHADER_RESOURCE_COMPUTE, ResourceState::UNORDERED_ACCESS), }; device->Barrier(barriers, arraysize(barriers), cmd); diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index b4bad3b62..fa0140754 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -529,11 +529,12 @@ namespace wi::scene device->CreateBuffer2(&buf, fill_dead_indices, &surfelgi.deadBuffer); device->SetName(&surfelgi.deadBuffer, "surfelgi.deadBuffer"); - buf.stride = sizeof(uint); - buf.size = SURFEL_STATS_SIZE; - buf.misc_flags = ResourceMiscFlag::BUFFER_RAW; - uint stats_data[] = { 0,0,SURFEL_CAPACITY,0,0,0 }; - device->CreateBuffer(&buf, &stats_data, &surfelgi.statsBuffer); + buf.stride = sizeof(SurfelStats); + buf.size = buf.stride; + buf.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; + SurfelStats stats = {}; + stats.deadCount = SURFEL_CAPACITY; + device->CreateBuffer(&buf, &stats, &surfelgi.statsBuffer); device->SetName(&surfelgi.statsBuffer, "surfelgi.statsBuffer"); buf.stride = sizeof(uint); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index e0cc327c3..1f7959825 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 72; // minor bug fixes, alterations, refactors, updates - const int revision = 30; + const int revision = 31; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);