Fix crash on particles sorting memory access

This commit is contained in:
Wojtek Figat
2025-08-04 10:31:52 +02:00
parent c9e0637b0f
commit abe496fe12
2 changed files with 24 additions and 17 deletions

View File

@@ -362,9 +362,10 @@ public:
uint32 histogram[RADIXSORT_HISTOGRAM_SIZE];
uint16 shift = 0;
int32 pass = 0;
for (; pass < 6; pass++)
constexpr int32 passCount = sizeof(T) >= sizeof(uint64) ? 6 : 3;
for (; pass < passCount; pass++)
{
Platform::MemoryClear(histogram, sizeof(uint32) * RADIXSORT_HISTOGRAM_SIZE);
Platform::MemoryClear(histogram, sizeof(histogram));
bool sorted = true;
T key = keys[0];
@@ -372,16 +373,14 @@ public:
for (int32 i = 0; i < count; i++)
{
key = keys[i];
const uint16 index = (key >> shift) & RADIXSORT_BIT_MASK;
const uint16 index = (key >> (T)shift) & RADIXSORT_BIT_MASK;
++histogram[index];
sorted &= prevKey <= key;
prevKey = key;
}
if (sorted)
{
goto end;
}
uint32 offset = 0;
for (int32 i = 0; i < RADIXSORT_HISTOGRAM_SIZE; ++i)
@@ -394,7 +393,7 @@ public:
for (int32 i = 0; i < count; i++)
{
const T k = keys[i];
const uint16 index = (k >> shift) & RADIXSORT_BIT_MASK;
const uint16 index = (k >> (T)shift) & RADIXSORT_BIT_MASK;
const uint32 dest = histogram[index]++;
tempKeys[dest] = k;
tempValues[dest] = values[i];

View File

@@ -4,7 +4,6 @@
#include "ParticleEffect.h"
#include "Engine/Content/Assets/Model.h"
#include "Engine/Core/Collections/Sorting.h"
#include "Engine/Core/Collections/HashSet.h"
#include "Engine/Engine/EngineService.h"
#include "Engine/Engine/Time.h"
#include "Engine/Engine/Engine.h"
@@ -216,14 +215,17 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
{
case ParticleSortMode::ViewDepth:
{
const int32 positionOffset = emitter->Graph.GetPositionAttributeOffset();
if (positionOffset == -1)
break;
const Matrix viewProjection = renderContext.View.ViewProjection();
byte* positionPtr = buffer->CPU.Buffer.Get() + emitter->Graph.GetPositionAttributeOffset();
const byte* positionPtr = buffer->CPU.Buffer.Get() + positionOffset;
if (emitter->SimulationSpace == ParticlesSimulationSpace::Local)
{
for (int32 i = 0; i < buffer->CPU.Count; i++)
{
// TODO: use SIMD
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(Matrix::TransformPosition(viewProjection, Matrix::TransformPosition(drawCall.World, *(Float3*)positionPtr)).W) ^ sortKeyXor;
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(Matrix::TransformPosition(viewProjection, Matrix::TransformPosition(drawCall.World, *(const Float3*)positionPtr)).W) ^ sortKeyXor;
positionPtr += stride;
}
}
@@ -231,7 +233,7 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
{
for (int32 i = 0; i < buffer->CPU.Count; i++)
{
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(Matrix::TransformPosition(viewProjection, *(Float3*)positionPtr).W) ^ sortKeyXor;
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(Matrix::TransformPosition(viewProjection, *(const Float3*)positionPtr).W) ^ sortKeyXor;
positionPtr += stride;
}
}
@@ -239,14 +241,17 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
}
case ParticleSortMode::ViewDistance:
{
const int32 positionOffset = emitter->Graph.GetPositionAttributeOffset();
if (positionOffset == -1)
break;
const Float3 viewPosition = renderContext.View.Position;
byte* positionPtr = buffer->CPU.Buffer.Get() + emitter->Graph.GetPositionAttributeOffset();
const byte* positionPtr = buffer->CPU.Buffer.Get() + positionOffset;
if (emitter->SimulationSpace == ParticlesSimulationSpace::Local)
{
for (int32 i = 0; i < buffer->CPU.Count; i++)
{
// TODO: use SIMD
sortedKeys[i] = RenderTools::ComputeDistanceSortKey((viewPosition - Float3::Transform(*(Float3*)positionPtr, drawCall.World)).LengthSquared()) ^ sortKeyXor;
sortedKeys[i] = RenderTools::ComputeDistanceSortKey((viewPosition - Float3::Transform(*(const Float3*)positionPtr, drawCall.World)).LengthSquared()) ^ sortKeyXor;
positionPtr += stride;
}
}
@@ -255,7 +260,7 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
for (int32 i = 0; i < buffer->CPU.Count; i++)
{
// TODO: use SIMD
sortedKeys[i] = RenderTools::ComputeDistanceSortKey((viewPosition - *(Float3*)positionPtr).LengthSquared()) ^ sortKeyXor;
sortedKeys[i] = RenderTools::ComputeDistanceSortKey((viewPosition - *(const Float3*)positionPtr).LengthSquared()) ^ sortKeyXor;
positionPtr += stride;
}
}
@@ -264,13 +269,16 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
case ParticleSortMode::CustomAscending:
case ParticleSortMode::CustomDescending:
{
int32 attributeIdx = module->Attributes[0];
const int32 attributeIdx = module->Attributes[0];
if (attributeIdx == -1)
break;
byte* attributePtr = buffer->CPU.Buffer.Get() + emitter->Graph.Layout.Attributes[attributeIdx].Offset;
const int32 attributeOffset = emitter->Graph.Layout.Attributes[attributeIdx].Offset;
if (attributeOffset == -1)
break;
const byte* attributePtr = buffer->CPU.Buffer.Get() + attributeOffset;
for (int32 i = 0; i < buffer->CPU.Count; i++)
{
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(*(float*)attributePtr) ^ sortKeyXor;
sortedKeys[i] = RenderTools::ComputeDistanceSortKey(*(const float*)attributePtr) ^ sortKeyXor;
attributePtr += stride;
}
break;
@@ -286,7 +294,7 @@ void DrawEmitterCPU(RenderContext& renderContext, ParticleBuffer* buffer, DrawCa
{
ParticlesDrawCPU::SortedIndices.Resize(listSize);
sortedIndices = ParticlesDrawCPU::SortedIndices.Get();
for (int i = 0; i < listSize; i++)
for (int32 i = 0; i < listSize; i++)
sortedIndices[i] = i;
}