Emitter, surfelgi, GPU sort refactor (#1541)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// in "Maximizing Parallelism in the Construction of BVHs, Octrees,
|
||||
// and k-d Trees"
|
||||
|
||||
ByteAddressBuffer primitiveCounterBuffer : register(t0);
|
||||
StructuredBuffer<uint> primitiveCounterBuffer : register(t0);
|
||||
StructuredBuffer<uint> primitiveIDBuffer : register(t1);
|
||||
StructuredBuffer<float> 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)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Parent node will merge child AABBs and store
|
||||
// Loop until we reach the root...
|
||||
|
||||
ByteAddressBuffer primitiveCounterBuffer : register(t0);
|
||||
StructuredBuffer<uint> primitiveCounterBuffer : register(t0);
|
||||
StructuredBuffer<uint> primitiveIDBuffer : register(t1);
|
||||
ByteAddressBuffer primitiveBuffer : register(t2);
|
||||
StructuredBuffer<uint> bvhParentBuffer : register(t3);
|
||||
@@ -18,7 +18,7 @@ RWStructuredBuffer<uint> 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)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ static const float3 BILLBOARD[] = {
|
||||
};
|
||||
static const uint BILLBOARD_VERTEXCOUNT = 4;
|
||||
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
StructuredBuffer<ParticleCounters> counterBuffer : register(t0);
|
||||
StructuredBuffer<Particle> particleBuffer : register(t1);
|
||||
StructuredBuffer<uint> culledIndirectionBuffer : register(t2);
|
||||
StructuredBuffer<uint> 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
|
||||
|
||||
@@ -15,7 +15,7 @@ RWStructuredBuffer<Particle> particleBuffer : register(u0);
|
||||
RWStructuredBuffer<uint> aliveBuffer_CURRENT : register(u1);
|
||||
RWStructuredBuffer<uint> aliveBuffer_NEW : register(u2);
|
||||
RWStructuredBuffer<uint> deadBuffer : register(u3);
|
||||
RWByteAddressBuffer counterBuffer : register(u4);
|
||||
RWStructuredBuffer<ParticleCounters> 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;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_EmittedParticle.h"
|
||||
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
StructuredBuffer<ParticleCounters> counterBuffer : register(t0);
|
||||
|
||||
RWStructuredBuffer<EmitterIndirectArgs> 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)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_EmittedParticle.h"
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u4);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u4);
|
||||
RWStructuredBuffer<EmitterIndirectArgs> 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<int>(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<int>(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;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ RWStructuredBuffer<Particle> particleBuffer : register(u0);
|
||||
RWStructuredBuffer<uint> aliveBuffer_CURRENT : register(u1);
|
||||
RWStructuredBuffer<uint> aliveBuffer_NEW : register(u2);
|
||||
RWStructuredBuffer<uint> deadBuffer : register(u3);
|
||||
RWByteAddressBuffer counterBuffer : register(u4);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u4);
|
||||
RWStructuredBuffer<float> distanceBuffer : register(u6);
|
||||
RWBuffer<float4> vertexBuffer_POS : register(u7);
|
||||
RWBuffer<float4> vertexBuffer_NOR : register(u8);
|
||||
@@ -32,7 +32,7 @@ RWStructuredBuffer<uint> 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;
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
StructuredBuffer<uint> aliveBuffer_CURRENT : register(t0);
|
||||
StructuredBuffer<Particle> particleBuffer : register(t1);
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u0);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u0);
|
||||
RWStructuredBuffer<SPHGridCell> cellBuffer : register(u1);
|
||||
RWStructuredBuffer<uint> 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;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
StructuredBuffer<uint> aliveBuffer_CURRENT : register(t0);
|
||||
StructuredBuffer<Particle> particleBuffer : register(t1);
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u0);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u0);
|
||||
RWStructuredBuffer<SPHGridCell> 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
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ StructuredBuffer<Particle> particleBuffer : register(t1);
|
||||
StructuredBuffer<uint> particleCellBuffer : register(t2);
|
||||
StructuredBuffer<SPHGridCell> cellBuffer : register(t3);
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u0);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u0);
|
||||
RWStructuredBuffer<float> 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;
|
||||
|
||||
@@ -8,7 +8,7 @@ StructuredBuffer<float> densityBuffer : register(t1);
|
||||
StructuredBuffer<uint> particleCellBuffer : register(t2);
|
||||
StructuredBuffer<SPHGridCell> cellBuffer : register(t3);
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u0);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u0);
|
||||
RWStructuredBuffer<Particle> 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;
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
StructuredBuffer<uint> aliveBuffer_CURRENT : register(t0);
|
||||
StructuredBuffer<Particle> particleBuffer : register(t1);
|
||||
|
||||
RWByteAddressBuffer counterBuffer : register(u0);
|
||||
RWStructuredBuffer<ParticleCounters> counterBuffer : register(u0);
|
||||
RWStructuredBuffer<SPHGridCell> 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;
|
||||
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_GPUSortLib.h"
|
||||
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
|
||||
RWByteAddressBuffer indirectBuffers : register(u0);
|
||||
RWStructuredBuffer<IndirectDispatchArgs> 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;
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Structured Buffers
|
||||
//--------------------------------------------------------------------------------------
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
StructuredBuffer<float> comparisonBuffer : register(t1);
|
||||
StructuredBuffer<float> comparisonBuffer : register(t0);
|
||||
|
||||
RWStructuredBuffer<uint> 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;
|
||||
|
||||
@@ -32,28 +32,19 @@
|
||||
#define NUM_THREADS (SORT_SIZE/2)
|
||||
#define INVERSION (16*2 + 8*3)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Structured Buffers
|
||||
//--------------------------------------------------------------------------------------
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
StructuredBuffer<float> comparisonBuffer : register(t1);
|
||||
StructuredBuffer<float> comparisonBuffer : register(t0);
|
||||
|
||||
RWStructuredBuffer<uint> 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;
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_GPUSortLib.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Structured Buffers
|
||||
//--------------------------------------------------------------------------------------
|
||||
ByteAddressBuffer counterBuffer : register(t0);
|
||||
StructuredBuffer<float> comparisonBuffer : register(t1);
|
||||
PUSHCONSTANT(sort, SortConstants);
|
||||
|
||||
StructuredBuffer<float> comparisonBuffer : register(t0);
|
||||
|
||||
RWStructuredBuffer<uint> indexBuffer : register(u0);
|
||||
|
||||
@@ -35,7 +33,7 @@ RWStructuredBuffer<uint> 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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
StructuredBuffer<Surfel> surfelBuffer : register(t0);
|
||||
StructuredBuffer<uint> surfelAliveBuffer : register(t1);
|
||||
ByteAddressBuffer surfelStatsBuffer : register(t2);
|
||||
StructuredBuffer<SurfelStats> surfelStatsBuffer : register(t2);
|
||||
|
||||
RWStructuredBuffer<SurfelGridCell> surfelGridBuffer : register(u0);
|
||||
RWStructuredBuffer<uint> surfelCellBuffer : register(u1);
|
||||
@@ -11,7 +11,7 @@ RWStructuredBuffer<uint> 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;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Texture2D<float2> surfelMomentsTexture : register(t3);
|
||||
RWStructuredBuffer<SurfelData> surfelDataBuffer : register(u0);
|
||||
RWStructuredBuffer<uint> surfelDeadBuffer : register(u1);
|
||||
RWStructuredBuffer<uint> surfelAliveBuffer : register(u2);
|
||||
RWByteAddressBuffer surfelStatsBuffer : register(u3);
|
||||
RWStructuredBuffer<SurfelStats> surfelStatsBuffer : register(u3);
|
||||
RWTexture2D<float3> result : register(u4);
|
||||
RWTexture2D<unorm float4> 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;
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
RWStructuredBuffer<SurfelGridCell> surfelGridBuffer : register(u0);
|
||||
RWStructuredBuffer<uint> surfelCellBuffer : register(u1);
|
||||
RWByteAddressBuffer surfelStatsBuffer : register(u2);
|
||||
RWStructuredBuffer<SurfelStats> 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;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
#include "globals.hlsli"
|
||||
#include "ShaderInterop_SurfelGI.h"
|
||||
|
||||
RWByteAddressBuffer surfelStatsBuffer : register(u0);
|
||||
RWStructuredBuffer<SurfelStats> surfelStatsBuffer : register(u0);
|
||||
RWStructuredBuffer<SurfelIndirectArgs> 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;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
PUSHCONSTANT(push, PushConstantsSurfelRaytrace);
|
||||
|
||||
StructuredBuffer<Surfel> surfelBuffer : register(t0);
|
||||
ByteAddressBuffer surfelStatsBuffer : register(t1);
|
||||
StructuredBuffer<SurfelStats> surfelStatsBuffer : register(t1);
|
||||
StructuredBuffer<SurfelGridCell> surfelGridBuffer : register(t2);
|
||||
StructuredBuffer<uint> surfelCellBuffer : register(t3);
|
||||
StructuredBuffer<uint> surfelAliveBuffer : register(t4);
|
||||
@@ -18,7 +18,7 @@ RWStructuredBuffer<SurfelRayDataPacked> 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;
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ RWStructuredBuffer<Surfel> surfelBuffer : register(u0);
|
||||
RWStructuredBuffer<SurfelGridCell> surfelGridBuffer : register(u1);
|
||||
RWStructuredBuffer<uint> surfelAliveBuffer_NEXT : register(u2);
|
||||
RWStructuredBuffer<uint> surfelDeadBuffer : register(u3);
|
||||
RWByteAddressBuffer surfelStatsBuffer : register(u4);
|
||||
RWStructuredBuffer<SurfelStats> surfelStatsBuffer : register(u4);
|
||||
RWStructuredBuffer<SurfelRayDataPacked> surfelRayBuffer : register(u5);
|
||||
RWStructuredBuffer<SurfelData> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
+18
-13
@@ -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
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user