Add RenderListAlloc to simplify rendering memory allocations
This commit is contained in:
@@ -210,31 +210,10 @@ void DrawEmitterCPU(RenderContextBatch& renderContextBatch, ParticleBuffer* buff
|
|||||||
const int32 stride = buffer->Stride;
|
const int32 stride = buffer->Stride;
|
||||||
const int32 listSize = buffer->CPU.Count;
|
const int32 listSize = buffer->CPU.Count;
|
||||||
const int32 indicesByteSize = listSize * buffer->GPU.SortedIndices->GetStride();
|
const int32 indicesByteSize = listSize * buffer->GPU.SortedIndices->GetStride();
|
||||||
Array<uint32, RendererAllocation> sortingKeysList[4];
|
RenderListAlloc sortingAllocs[4];
|
||||||
Array<byte, RendererAllocation> sortingIndicesList[2];
|
auto* renderList = renderContextBatch.GetMainContext().List;
|
||||||
uint32* sortingKeys[2];
|
uint32* sortingKeys[2] = { sortingAllocs[0].Init<uint32>(renderList, listSize), sortingAllocs[1].Init<uint32>(renderList, listSize) };
|
||||||
void* sortingIndices[2];
|
void* sortingIndices[2] = { sortingAllocs[2].Init(renderList, indicesByteSize, GPU_SHADER_DATA_ALIGNMENT), sortingAllocs[3].Init(renderList, indicesByteSize, GPU_SHADER_DATA_ALIGNMENT) };
|
||||||
if (listSize < 500)
|
|
||||||
{
|
|
||||||
// Use fast stack allocator from RenderList
|
|
||||||
auto& memory = renderContextBatch.GetMainContext().List->Memory;
|
|
||||||
sortingKeys[0] = memory.Allocate<uint32>(listSize);
|
|
||||||
sortingKeys[1] = memory.Allocate<uint32>(listSize);
|
|
||||||
sortingIndices[0] = memory.Allocate(indicesByteSize, GPU_SHADER_DATA_ALIGNMENT);
|
|
||||||
sortingIndices[1] = memory.Allocate(indicesByteSize, GPU_SHADER_DATA_ALIGNMENT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Use shared pooled memory from RendererAllocation
|
|
||||||
sortingKeysList[0].Resize(listSize);
|
|
||||||
sortingKeysList[1].Resize(listSize);
|
|
||||||
sortingIndicesList[0].Resize(indicesByteSize);
|
|
||||||
sortingIndicesList[1].Resize(indicesByteSize);
|
|
||||||
sortingKeys[0] = sortingKeysList[0].Get();
|
|
||||||
sortingKeys[1] = sortingKeysList[1].Get();
|
|
||||||
sortingIndices[0] = sortingIndicesList[0].Get();
|
|
||||||
sortingIndices[1] = sortingIndicesList[1].Get();
|
|
||||||
}
|
|
||||||
uint32* sortedKeys = sortingKeys[0];
|
uint32* sortedKeys = sortingKeys[0];
|
||||||
const uint32 sortKeyXor = sortMode != ParticleSortMode::CustomAscending ? MAX_uint32 : 0;
|
const uint32 sortKeyXor = sortMode != ParticleSortMode::CustomAscending ? MAX_uint32 : 0;
|
||||||
switch (sortMode)
|
switch (sortMode)
|
||||||
@@ -321,7 +300,7 @@ void DrawEmitterCPU(RenderContextBatch& renderContextBatch, ParticleBuffer* buff
|
|||||||
{
|
{
|
||||||
case PixelFormat::R16_UInt:
|
case PixelFormat::R16_UInt:
|
||||||
for (int32 i = 0; i < listSize; i++)
|
for (int32 i = 0; i < listSize; i++)
|
||||||
((uint16*)sortedIndices)[i] = i;
|
((uint16*)sortedIndices)[i] = (uint16)i;
|
||||||
break;
|
break;
|
||||||
case PixelFormat::R32_UInt:
|
case PixelFormat::R32_UInt:
|
||||||
for (int32 i = 0; i < listSize; i++)
|
for (int32 i = 0; i < listSize; i++)
|
||||||
|
|||||||
@@ -461,6 +461,25 @@ bool DrawCallsList::IsEmpty() const
|
|||||||
return Indices.Count() + PreBatchedDrawCalls.Count() == 0;
|
return Indices.Count() + PreBatchedDrawCalls.Count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderListAlloc::~RenderListAlloc()
|
||||||
|
{
|
||||||
|
if (!List && Data) // Render List memory doesn't need free (arena allocator)
|
||||||
|
RendererAllocation::Free(Data, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* RenderListAlloc::Init(RenderList* list, uintptr size, uintptr alignment)
|
||||||
|
{
|
||||||
|
ASSERT_LOW_LAYER(!Data);
|
||||||
|
Size = size;
|
||||||
|
bool useList = alignment <= 16 && size < 1024;
|
||||||
|
List = useList ? list : nullptr;
|
||||||
|
if (useList)
|
||||||
|
Data = list->Memory.Allocate(size, alignment);
|
||||||
|
else
|
||||||
|
Data = RendererAllocation::Allocate(size);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
RenderList::RenderList(const SpawnParams& params)
|
RenderList::RenderList(const SpawnParams& params)
|
||||||
: ScriptingObject(params)
|
: ScriptingObject(params)
|
||||||
, Memory(4 * 1024 * 1024, RendererAllocation::Allocate, RendererAllocation::Free) // 4MB pages, use page pooling via RendererAllocation
|
, Memory(4 * 1024 * 1024, RendererAllocation::Allocate, RendererAllocation::Free) // 4MB pages, use page pooling via RendererAllocation
|
||||||
@@ -692,12 +711,10 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
|
|||||||
ZoneValue(listSize);
|
ZoneValue(listSize);
|
||||||
|
|
||||||
// Use shared memory from renderer allocator
|
// Use shared memory from renderer allocator
|
||||||
Array<uint64, RendererAllocation> SortingKeys[2];
|
RenderListAlloc allocs[3];
|
||||||
Array<int32, RendererAllocation> SortingIndices;
|
uint64* sortedKeys = allocs[0].Init<uint64>(this, listSize);
|
||||||
SortingKeys[0].Resize(listSize);
|
uint64* tempKeys = allocs[1].Init<uint64>(this, listSize);
|
||||||
SortingKeys[1].Resize(listSize);
|
int32* tempIndices = allocs[2].Init<int32>(this, listSize);
|
||||||
SortingIndices.Resize(listSize);
|
|
||||||
uint64* sortedKeys = SortingKeys[0].Get();
|
|
||||||
|
|
||||||
// Setup sort keys
|
// Setup sort keys
|
||||||
if (reverseDistance)
|
if (reverseDistance)
|
||||||
@@ -740,7 +757,7 @@ void RenderList::SortDrawCalls(const RenderContext& renderContext, bool reverseD
|
|||||||
|
|
||||||
// Sort draw calls indices
|
// Sort draw calls indices
|
||||||
int32* resultIndices = list.Indices.Get();
|
int32* resultIndices = list.Indices.Get();
|
||||||
Sorting::RadixSort(sortedKeys, resultIndices, SortingKeys[1].Get(), SortingIndices.Get(), listSize);
|
Sorting::RadixSort(sortedKeys, resultIndices, tempKeys, tempIndices, listSize);
|
||||||
if (resultIndices != list.Indices.Get())
|
if (resultIndices != list.Indices.Get())
|
||||||
Platform::MemoryCopy(list.Indices.Get(), resultIndices, sizeof(int32) * listSize);
|
Platform::MemoryCopy(list.Indices.Get(), resultIndices, sizeof(int32) * listSize);
|
||||||
|
|
||||||
|
|||||||
@@ -278,6 +278,30 @@ struct DrawCallsList
|
|||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Small utility for allocating memory from RenderList arena pool with automatic fallback to shared RendererAllocation for larger memory blocks.
|
||||||
|
struct RenderListAlloc
|
||||||
|
{
|
||||||
|
RenderList* List;
|
||||||
|
void* Data = nullptr;
|
||||||
|
uintptr Size;
|
||||||
|
|
||||||
|
~RenderListAlloc();
|
||||||
|
|
||||||
|
void* Init(RenderList* list, uintptr size, uintptr alignment = 1);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
FORCE_INLINE T* Init(RenderList* list, int32 count, uintptr alignment = 1)
|
||||||
|
{
|
||||||
|
return (T*)Init(list, count * sizeof(T), alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
FORCE_INLINE T* Get()
|
||||||
|
{
|
||||||
|
return (T*)Data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rendering cache container object for the draw calls collecting, sorting and executing.
|
/// Rendering cache container object for the draw calls collecting, sorting and executing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user