diff --git a/WickedEngine/ConstantBufferMapping.h b/WickedEngine/ConstantBufferMapping.h
index fda84204b..df2fb04f7 100644
--- a/WickedEngine/ConstantBufferMapping.h
+++ b/WickedEngine/ConstantBufferMapping.h
@@ -35,7 +35,7 @@
#define CBSLOT_OTHER_OCEAN_SIMULATION_PERFRAME 9
#define CBSLOT_OTHER_OCEAN_RENDER 8
#define CBSLOT_OTHER_CLOUDGENERATOR 8
-#define CBSLOT_OTHER_GPUSORTLIB 8
+#define CBSLOT_OTHER_GPUSORTLIB 9
diff --git a/WickedEngine/ShaderInterop_EmittedParticle.h b/WickedEngine/ShaderInterop_EmittedParticle.h
index b03b0165f..1a2482d3b 100644
--- a/WickedEngine/ShaderInterop_EmittedParticle.h
+++ b/WickedEngine/ShaderInterop_EmittedParticle.h
@@ -70,7 +70,7 @@ static const uint ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION = ARGUMENTBUFFER_OFFS
static const uint ARGUMENTBUFFER_OFFSET_DRAWPARTICLES = ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION + (3 * 4);
-static const uint SPH_PARTITION_BUCKET_COUNT = 64 * 64 * 64;
+static const uint SPH_PARTITION_BUCKET_COUNT = 128 * 128 * 128;
inline uint SPH_GridHash(int3 cellIndex)
{
diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj b/WickedEngine/WickedEngine_SHADERS.vcxproj
index c39d3431b..cdc8b107d 100644
--- a/WickedEngine/WickedEngine_SHADERS.vcxproj
+++ b/WickedEngine/WickedEngine_SHADERS.vcxproj
@@ -129,6 +129,14 @@
Compute
5.0
+
+ Compute
+ 5.0
+
+
+ Compute
+ 5.0
+
Compute
5.0
diff --git a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
index 4916f5ec6..028b07b29 100644
--- a/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
+++ b/WickedEngine/WickedEngine_SHADERS.vcxproj.filters
@@ -714,6 +714,12 @@
CS
+
+ CS
+
+
+ CS
+
diff --git a/WickedEngine/emittedparticle_sphpartitionCS.hlsl b/WickedEngine/emittedparticle_sphpartitionCS.hlsl
index 6369924ae..f255e289f 100644
--- a/WickedEngine/emittedparticle_sphpartitionCS.hlsl
+++ b/WickedEngine/emittedparticle_sphpartitionCS.hlsl
@@ -5,7 +5,7 @@ STRUCTUREDBUFFER(aliveBuffer_CURRENT, uint, 0);
RAWBUFFER(counterBuffer, 1);
STRUCTUREDBUFFER(particleBuffer, Particle, 2);
-RWSTRUCTUREDBUFFER(cellIndexBuffer, uint, 0);
+RWSTRUCTUREDBUFFER(cellIndexBuffer, float, 0);
[numthreads(THREADCOUNT_SIMULATION, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
@@ -17,9 +17,12 @@ void main( uint3 DTid : SV_DispatchThreadID )
uint particleIndex = aliveBuffer_CURRENT[DTid.x];
Particle particle = particleBuffer[particleIndex];
- int3 cellIndex = floor(particle.position);
+ // Grid cell is of size [SPH smoothing radius], so position is refitted into that
+ float3 remappedPos = particle.position / xSPH_h; // optimize div??
+
+ int3 cellIndex = floor(remappedPos);
uint flatCellIndex = SPH_GridHash(cellIndex);
- cellIndexBuffer[particleIndex] = flatCellIndex;
+ cellIndexBuffer[particleIndex] = (float)flatCellIndex;
}
}
diff --git a/WickedEngine/emittedparticle_sphpartitionoffsetsCS.hlsl b/WickedEngine/emittedparticle_sphpartitionoffsetsCS.hlsl
new file mode 100644
index 000000000..0a5ca9e1e
--- /dev/null
+++ b/WickedEngine/emittedparticle_sphpartitionoffsetsCS.hlsl
@@ -0,0 +1,22 @@
+#include "globals.hlsli"
+#include "ShaderInterop_EmittedParticle.h"
+
+STRUCTUREDBUFFER(aliveBuffer_CURRENT, uint, 0);
+RAWBUFFER(counterBuffer, 1);
+STRUCTUREDBUFFER(cellIndexBuffer, float, 2);
+
+RWSTRUCTUREDBUFFER(cellOffsetBuffer, uint, 0);
+
+[numthreads(THREADCOUNT_SIMULATION, 1, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ uint aliveCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_ALIVECOUNT);
+
+ if (DTid.x < aliveCount)
+ {
+ uint particleIndex = aliveBuffer_CURRENT[DTid.x];
+ uint cellIndex = (uint)cellIndexBuffer[particleIndex];
+
+ InterlockedMin(cellOffsetBuffer[cellIndex], DTid.x);
+ }
+}
diff --git a/WickedEngine/emittedparticle_sphpartitionoffsetsresetCS.hlsl b/WickedEngine/emittedparticle_sphpartitionoffsetsresetCS.hlsl
new file mode 100644
index 000000000..108d31baa
--- /dev/null
+++ b/WickedEngine/emittedparticle_sphpartitionoffsetsresetCS.hlsl
@@ -0,0 +1,10 @@
+#include "globals.hlsli"
+#include "ShaderInterop_EmittedParticle.h"
+
+RWSTRUCTUREDBUFFER(cellOffsetBuffer, uint, 0);
+
+[numthreads(THREADCOUNT_SIMULATION, 1, 1)]
+void main(uint3 DTid : SV_DispatchThreadID)
+{
+ cellOffsetBuffer[DTid.x] = 0xFFFFFFFF; // invalid offset
+}
diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp
index 83ce51695..9ce9be553 100644
--- a/WickedEngine/wiEmittedParticle.cpp
+++ b/WickedEngine/wiEmittedParticle.cpp
@@ -15,15 +15,18 @@ using namespace wiGraphicsTypes;
VertexShader *wiEmittedParticle::vertexShader = nullptr;
PixelShader *wiEmittedParticle::pixelShader[PARTICLESHADERTYPE_COUNT] = {};
-ComputeShader *wiEmittedParticle::kickoffUpdateCS = nullptr, *wiEmittedParticle::finishUpdateCS = nullptr, *wiEmittedParticle::emitCS = nullptr, *wiEmittedParticle::sphdensityCS = nullptr, *wiEmittedParticle::sphforceCS = nullptr, *wiEmittedParticle::simulateCS = nullptr,
- *wiEmittedParticle::simulateCS_SORTING = nullptr, *wiEmittedParticle::simulateCS_DEPTHCOLLISIONS = nullptr, *wiEmittedParticle::simulateCS_SORTING_DEPTHCOLLISIONS = nullptr;
+ComputeShader *wiEmittedParticle::kickoffUpdateCS = nullptr, *wiEmittedParticle::finishUpdateCS = nullptr, *wiEmittedParticle::emitCS = nullptr, *wiEmittedParticle::sphpartitionCS = nullptr,
+ *wiEmittedParticle::sphpartitionoffsetsCS = nullptr, *wiEmittedParticle::sphpartitionoffsetsresetCS = nullptr, *wiEmittedParticle::sphdensityCS = nullptr, *wiEmittedParticle::sphforceCS = nullptr,
+ *wiEmittedParticle::simulateCS = nullptr, *wiEmittedParticle::simulateCS_SORTING = nullptr, *wiEmittedParticle::simulateCS_DEPTHCOLLISIONS = nullptr, *wiEmittedParticle::simulateCS_SORTING_DEPTHCOLLISIONS = nullptr;
+
BlendState wiEmittedParticle::blendStates[BLENDMODE_COUNT];
RasterizerState wiEmittedParticle::rasterizerState, wiEmittedParticle::wireFrameRS;
DepthStencilState wiEmittedParticle::depthStencilState;
GraphicsPSO wiEmittedParticle::PSO[BLENDMODE_COUNT][PARTICLESHADERTYPE_COUNT];
GraphicsPSO wiEmittedParticle::PSO_wire;
-ComputePSO wiEmittedParticle::CPSO_kickoffUpdate, wiEmittedParticle::CPSO_finishUpdate, wiEmittedParticle::CPSO_emit, wiEmittedParticle::CPSO_sphdensity, wiEmittedParticle::CPSO_sphforce, wiEmittedParticle::CPSO_simulate,
- wiEmittedParticle::CPSO_simulate_SORTING, wiEmittedParticle::CPSO_simulate_DEPTHCOLLISIONS, wiEmittedParticle::CPSO_simulate_SORTING_DEPTHCOLLISIONS;
+ComputePSO wiEmittedParticle::CPSO_kickoffUpdate, wiEmittedParticle::CPSO_finishUpdate, wiEmittedParticle::CPSO_emit, wiEmittedParticle::CPSO_sphpartition, wiEmittedParticle::CPSO_sphpartitionoffsets,
+ wiEmittedParticle::CPSO_sphpartitionoffsetsreset, wiEmittedParticle::CPSO_sphdensity, wiEmittedParticle::CPSO_sphforce, wiEmittedParticle::CPSO_simulate,
+ wiEmittedParticle::CPSO_simulate_SORTING, wiEmittedParticle::CPSO_simulate_DEPTHCOLLISIONS, wiEmittedParticle::CPSO_simulate_SORTING_DEPTHCOLLISIONS;
wiEmittedParticle::wiEmittedParticle()
{
@@ -47,19 +50,6 @@ wiEmittedParticle::wiEmittedParticle()
motionBlurAmount = 0.0f;
- SAFE_INIT(particleBuffer);
- SAFE_INIT(aliveList[0]);
- SAFE_INIT(aliveList[1]);
- SAFE_INIT(deadList);
- SAFE_INIT(distanceBuffer);
- SAFE_INIT(densityBuffer);
- SAFE_INIT(counterBuffer);
- SAFE_INIT(indirectBuffers);
- SAFE_INIT(constantBuffer);
- SAFE_INIT(debugDataReadbackBuffer);
- SAFE_INIT(debugDataReadbackIndexBuffer);
- SAFE_INIT(debugDataReadbackDistanceBuffer);
-
SetMaxParticleCount(10000);
}
wiEmittedParticle::wiEmittedParticle(const std::string& newName, const std::string& newMat, Object* newObject, float newSize, float newRandomFac, float newNormalFac
@@ -91,20 +81,6 @@ wiEmittedParticle::wiEmittedParticle(const std::string& newName, const std::stri
motionBlurAmount = 0.0f;
-
- SAFE_INIT(particleBuffer);
- SAFE_INIT(aliveList[0]);
- SAFE_INIT(aliveList[1]);
- SAFE_INIT(deadList);
- SAFE_INIT(distanceBuffer);
- SAFE_INIT(densityBuffer);
- SAFE_INIT(counterBuffer);
- SAFE_INIT(indirectBuffers);
- SAFE_INIT(constantBuffer);
- SAFE_INIT(debugDataReadbackBuffer);
- SAFE_INIT(debugDataReadbackIndexBuffer);
- SAFE_INIT(debugDataReadbackDistanceBuffer);
-
SetMaxParticleCount(10000);
}
wiEmittedParticle::wiEmittedParticle(const wiEmittedParticle& other)
@@ -125,20 +101,6 @@ wiEmittedParticle::wiEmittedParticle(const wiEmittedParticle& other)
rotation = other.rotation;
motionBlurAmount = other.motionBlurAmount;
-
- SAFE_INIT(particleBuffer);
- SAFE_INIT(aliveList[0]);
- SAFE_INIT(aliveList[1]);
- SAFE_INIT(deadList);
- SAFE_INIT(distanceBuffer);
- SAFE_INIT(densityBuffer);
- SAFE_INIT(counterBuffer);
- SAFE_INIT(indirectBuffers);
- SAFE_INIT(constantBuffer);
- SAFE_INIT(debugDataReadbackBuffer);
- SAFE_INIT(debugDataReadbackIndexBuffer);
- SAFE_INIT(debugDataReadbackDistanceBuffer);
-
SetMaxParticleCount(other.GetMaxParticleCount());
}
@@ -161,6 +123,8 @@ void wiEmittedParticle::CreateSelfBuffers()
SAFE_DELETE(aliveList[1]);
SAFE_DELETE(deadList);
SAFE_DELETE(distanceBuffer);
+ SAFE_DELETE(sphPartitionCellIndices);
+ SAFE_DELETE(sphPartitionCellOffsets);
SAFE_DELETE(densityBuffer);
SAFE_DELETE(counterBuffer);
SAFE_DELETE(indirectBuffers);
@@ -174,6 +138,8 @@ void wiEmittedParticle::CreateSelfBuffers()
aliveList[1] = new GPUBuffer;
deadList = new GPUBuffer;
distanceBuffer = new GPUBuffer;
+ sphPartitionCellIndices = new GPUBuffer;
+ sphPartitionCellOffsets = new GPUBuffer;
densityBuffer = new GPUBuffer;
counterBuffer = new GPUBuffer;
indirectBuffers = new GPUBuffer;
@@ -226,6 +192,16 @@ void wiEmittedParticle::CreateSelfBuffers()
SAFE_DELETE_ARRAY(distances);
data.pSysMem = nullptr;
+ // SPH Partitioning grid indices per particle:
+ bd.StructureByteStride = sizeof(float); // really, it is uint, but sorting is performing comparisons on floats, so whateva
+ bd.ByteWidth = bd.StructureByteStride * MAX_PARTICLES;
+ wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, sphPartitionCellIndices);
+
+ // SPH Partitioning grid cell offsets into particle index list:
+ bd.StructureByteStride = sizeof(uint32_t);
+ bd.ByteWidth = bd.StructureByteStride * SPH_PARTITION_BUCKET_COUNT;
+ wiRenderer::GetDevice()->CreateBuffer(&bd, nullptr, sphPartitionCellOffsets);
+
// Density buffer (for SPH simulation):
bd.StructureByteStride = sizeof(float);
bd.ByteWidth = bd.StructureByteStride * MAX_PARTICLES;
@@ -303,6 +279,8 @@ uint32_t wiEmittedParticle::GetMemorySizeInBytes() const
retVal += aliveList[1]->GetDesc().ByteWidth;
retVal += deadList->GetDesc().ByteWidth;
retVal += distanceBuffer->GetDesc().ByteWidth;
+ retVal += sphPartitionCellIndices->GetDesc().ByteWidth;
+ retVal += sphPartitionCellOffsets->GetDesc().ByteWidth;
retVal += densityBuffer->GetDesc().ByteWidth;
retVal += counterBuffer->GetDesc().ByteWidth;
retVal += indirectBuffers->GetDesc().ByteWidth;
@@ -419,8 +397,56 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
if (SPH_FLUIDSIMULATION)
{
// Smooth Particle Hydrodynamics:
+ device->EventBegin("SPH - Simulation", threadID);
- // 1.) Compute particle density field:
+ // 1.) Assign particles into partitioning grid:
+ device->EventBegin("Partitioning", threadID);
+ device->BindComputePSO(&CPSO_sphpartition, threadID);
+ device->UnBindUnorderedAccessResources(0, 8, threadID);
+ GPUResource* res_partition[] = {
+ aliveList[0], // CURRENT alivelist
+ counterBuffer,
+ particleBuffer,
+ };
+ device->BindResources(CS, res_partition, 0, ARRAYSIZE(res_partition), threadID);
+ GPUResource* uav_partition[] = {
+ sphPartitionCellIndices,
+ };
+ device->BindUnorderedAccessResourcesCS(uav_partition, 0, ARRAYSIZE(uav_partition), threadID);
+ device->DispatchIndirect(indirectBuffers, ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION, threadID);
+ device->UAVBarrier(uav_partition, ARRAYSIZE(uav_partition), threadID);
+ device->EventEnd(threadID);
+
+ // 2.) Sort particle index list based on partition grid cell index:
+ wiGPUSortLib::Sort(MAX_PARTICLES, sphPartitionCellIndices, counterBuffer, PARTICLECOUNTER_OFFSET_ALIVECOUNT, aliveList[0], threadID);
+
+ // 3.) Reset grid cell offset buffer with invalid offsets (max uint):
+ device->EventBegin("PartitionOffsetsReset", threadID);
+ device->BindComputePSO(&CPSO_sphpartitionoffsetsreset, threadID);
+ device->UnBindUnorderedAccessResources(0, 8, threadID);
+ GPUResource* uav_partitionoffsets[] = {
+ sphPartitionCellOffsets,
+ };
+ device->BindUnorderedAccessResourcesCS(uav_partitionoffsets, 0, ARRAYSIZE(uav_partitionoffsets), threadID);
+ device->Dispatch((UINT)ceilf((float)SPH_PARTITION_BUCKET_COUNT / (float)THREADCOUNT_SIMULATION), 1, 1, threadID);
+ device->UAVBarrier(uav_partitionoffsets, ARRAYSIZE(uav_partitionoffsets), threadID);
+ device->EventEnd(threadID);
+
+ // 4.) Assemble grid cell offsets from the sorted particle index list <--> grid cell index list connection:
+ device->EventBegin("PartitionOffsets", threadID);
+ device->BindComputePSO(&CPSO_sphpartitionoffsets, threadID);
+ GPUResource* res_partitionoffsets[] = {
+ aliveList[0], // CURRENT alivelist
+ counterBuffer,
+ sphPartitionCellIndices,
+ };
+ device->BindResources(CS, res_partitionoffsets, 0, ARRAYSIZE(res_partitionoffsets), threadID);
+ device->DispatchIndirect(indirectBuffers, ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION, threadID);
+ device->UAVBarrier(uav_partitionoffsets, ARRAYSIZE(uav_partitionoffsets), threadID);
+ device->EventEnd(threadID);
+
+ // 5.) Compute particle density field:
+ device->EventBegin("Density Evaluation", threadID);
device->BindComputePSO(&CPSO_sphdensity, threadID);
device->UnBindUnorderedAccessResources(0, 8, threadID);
GPUResource* res_density[] = {
@@ -434,9 +460,11 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
};
device->BindUnorderedAccessResourcesCS(uav_density, 0, ARRAYSIZE(uav_density), threadID);
device->DispatchIndirect(indirectBuffers, ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION, threadID);
- device->UAVBarrier(uavs, ARRAYSIZE(uavs), threadID);
+ device->UAVBarrier(uav_density, ARRAYSIZE(uav_density), threadID);
+ device->EventEnd(threadID);
- // 2.) Compute particle pressure forces:
+ // 6.) Compute particle pressure forces:
+ device->EventBegin("Force Evaluation", threadID);
device->BindComputePSO(&CPSO_sphforce, threadID);
device->UnBindUnorderedAccessResources(0, 8, threadID);
GPUResource* res_force[] = {
@@ -450,10 +478,13 @@ void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
};
device->BindUnorderedAccessResourcesCS(uav_force, 0, ARRAYSIZE(uav_force), threadID);
device->DispatchIndirect(indirectBuffers, ARGUMENTBUFFER_OFFSET_DISPATCHSIMULATION, threadID);
- device->UAVBarrier(uavs, ARRAYSIZE(uavs), threadID);
+ device->UAVBarrier(uav_force, ARRAYSIZE(uav_force), threadID);
+ device->EventEnd(threadID);
device->UnBindResources(0, 3, threadID);
device->UnBindUnorderedAccessResources(0, 8, threadID);
+
+ device->EventEnd(threadID);
}
device->BindUnorderedAccessResourcesCS(uavs, 0, ARRAYSIZE(uavs), threadID);
@@ -663,6 +694,9 @@ void wiEmittedParticle::LoadShaders()
kickoffUpdateCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_kickoffUpdateCS.cso", wiResourceManager::COMPUTESHADER));
finishUpdateCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_finishUpdateCS.cso", wiResourceManager::COMPUTESHADER));
emitCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_emitCS.cso", wiResourceManager::COMPUTESHADER));
+ sphpartitionCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_sphpartitionCS.cso", wiResourceManager::COMPUTESHADER));
+ sphpartitionoffsetsCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_sphpartitionoffsetsCS.cso", wiResourceManager::COMPUTESHADER));
+ sphpartitionoffsetsresetCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_sphpartitionoffsetsresetCS.cso", wiResourceManager::COMPUTESHADER));
sphdensityCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_sphdensityCS.cso", wiResourceManager::COMPUTESHADER));
sphforceCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_sphforceCS.cso", wiResourceManager::COMPUTESHADER));
simulateCS = static_cast(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "emittedparticle_simulateCS.cso", wiResourceManager::COMPUTESHADER));
@@ -716,6 +750,15 @@ void wiEmittedParticle::LoadShaders()
desc.cs = emitCS;
device->CreateComputePSO(&desc, &CPSO_emit);
+ desc.cs = sphpartitionCS;
+ device->CreateComputePSO(&desc, &CPSO_sphpartition);
+
+ desc.cs = sphpartitionoffsetsCS;
+ device->CreateComputePSO(&desc, &CPSO_sphpartitionoffsets);
+
+ desc.cs = sphpartitionoffsetsresetCS;
+ device->CreateComputePSO(&desc, &CPSO_sphpartitionoffsetsreset);
+
desc.cs = sphdensityCS;
device->CreateComputePSO(&desc, &CPSO_sphdensity);
diff --git a/WickedEngine/wiEmittedParticle.h b/WickedEngine/wiEmittedParticle.h
index 6a5998996..8ba4f1f81 100644
--- a/WickedEngine/wiEmittedParticle.h
+++ b/WickedEngine/wiEmittedParticle.h
@@ -23,21 +23,23 @@ public:
private:
ParticleCounters debugData = {};
- wiGraphicsTypes::GPUBuffer* debugDataReadbackBuffer;
- wiGraphicsTypes::GPUBuffer* debugDataReadbackIndexBuffer;
- wiGraphicsTypes::GPUBuffer* debugDataReadbackDistanceBuffer;
+ wiGraphicsTypes::GPUBuffer* debugDataReadbackBuffer = nullptr;
+ wiGraphicsTypes::GPUBuffer* debugDataReadbackIndexBuffer = nullptr;
+ wiGraphicsTypes::GPUBuffer* debugDataReadbackDistanceBuffer = nullptr;
- wiGraphicsTypes::GPUBuffer* particleBuffer;
- wiGraphicsTypes::GPUBuffer* aliveList[2];
- wiGraphicsTypes::GPUBuffer* deadList;
- wiGraphicsTypes::GPUBuffer* distanceBuffer; // for sorting
- wiGraphicsTypes::GPUBuffer* densityBuffer; // for SPH
- wiGraphicsTypes::GPUBuffer* counterBuffer;
- wiGraphicsTypes::GPUBuffer* indirectBuffers; // kickoffUpdate, simulation, draw
- wiGraphicsTypes::GPUBuffer* constantBuffer;
+ wiGraphicsTypes::GPUBuffer* particleBuffer = nullptr;
+ wiGraphicsTypes::GPUBuffer* aliveList[2] = { nullptr, nullptr };
+ wiGraphicsTypes::GPUBuffer* deadList = nullptr;
+ wiGraphicsTypes::GPUBuffer* distanceBuffer = nullptr; // for sorting
+ wiGraphicsTypes::GPUBuffer* sphPartitionCellIndices = nullptr; // for SPH
+ wiGraphicsTypes::GPUBuffer* sphPartitionCellOffsets = nullptr; // for SPH
+ wiGraphicsTypes::GPUBuffer* densityBuffer = nullptr; // for SPH
+ wiGraphicsTypes::GPUBuffer* counterBuffer = nullptr;
+ wiGraphicsTypes::GPUBuffer* indirectBuffers = nullptr; // kickoffUpdate, simulation, draw
+ wiGraphicsTypes::GPUBuffer* constantBuffer = nullptr;
void CreateSelfBuffers();
- static wiGraphicsTypes::ComputeShader *kickoffUpdateCS, *finishUpdateCS, *emitCS, *sphdensityCS, *sphforceCS, *simulateCS, *simulateCS_SORTING, *simulateCS_DEPTHCOLLISIONS, *simulateCS_SORTING_DEPTHCOLLISIONS;
+ static wiGraphicsTypes::ComputeShader *kickoffUpdateCS, *finishUpdateCS, *emitCS, *sphpartitionCS, *sphpartitionoffsetsCS, *sphpartitionoffsetsresetCS, *sphdensityCS, *sphforceCS, *simulateCS, *simulateCS_SORTING, *simulateCS_DEPTHCOLLISIONS, *simulateCS_SORTING_DEPTHCOLLISIONS;
static wiGraphicsTypes::VertexShader *vertexShader;
static wiGraphicsTypes::PixelShader *pixelShader[PARTICLESHADERTYPE_COUNT];
static wiGraphicsTypes::BlendState blendStates[BLENDMODE_COUNT];
@@ -46,7 +48,7 @@ private:
static wiGraphicsTypes::GraphicsPSO PSO[BLENDMODE_COUNT][PARTICLESHADERTYPE_COUNT];
static wiGraphicsTypes::GraphicsPSO PSO_wire;
- static wiGraphicsTypes::ComputePSO CPSO_kickoffUpdate, CPSO_finishUpdate, CPSO_emit, CPSO_sphdensity, CPSO_sphforce, CPSO_simulate, CPSO_simulate_SORTING, CPSO_simulate_DEPTHCOLLISIONS, CPSO_simulate_SORTING_DEPTHCOLLISIONS;
+ static wiGraphicsTypes::ComputePSO CPSO_kickoffUpdate, CPSO_finishUpdate, CPSO_emit, CPSO_sphpartition, CPSO_sphpartitionoffsets, CPSO_sphpartitionoffsetsreset, CPSO_sphdensity, CPSO_sphforce, CPSO_simulate, CPSO_simulate_SORTING, CPSO_simulate_DEPTHCOLLISIONS, CPSO_simulate_SORTING_DEPTHCOLLISIONS;
public:
static void LoadShaders();
diff --git a/WickedEngine/wiGPUSortLib.cpp b/WickedEngine/wiGPUSortLib.cpp
index b9a61ccda..aa167e758 100644
--- a/WickedEngine/wiGPUSortLib.cpp
+++ b/WickedEngine/wiGPUSortLib.cpp
@@ -90,6 +90,7 @@ void wiGPUSortLib::Sort(UINT maxCount, GPUBuffer* comparisonBuffer_read, GPUBuff
device->UpdateBuffer(sortCB, &sc, threadID);
device->BindConstantBuffer(CS, sortCB, CB_GETBINDSLOT(SortConstants), threadID);
+ device->UnBindUnorderedAccessResources(0, 8, threadID);
// initialize sorting arguments:
{
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index f82303d08..8851f7952 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 17;
// minor bug fixes, alterations, refactors, updates
- const int revision = 19;
+ const int revision = 20;
long GetVersion()