Optimize renderer memory allocations with RenderListAllocation (mem pooling)
This commit is contained in:
@@ -174,7 +174,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef Array<struct BatchedDrawCall, InlinedAllocation<8>> DrawCallsList;
|
typedef Array<struct BatchedDrawCall, InlinedAllocation<8>> DrawCallsList;
|
||||||
typedef Dictionary<DrawKey, struct BatchedDrawCall, HeapAllocation> BatchedDrawCalls;
|
typedef Dictionary<DrawKey, struct BatchedDrawCall, class RenderListAllocation> BatchedDrawCalls;
|
||||||
void DrawInstance(RenderContext& renderContext, FoliageInstance& instance, FoliageType& type, Model* model, int32 lod, float lodDitherFactor, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const;
|
void DrawInstance(RenderContext& renderContext, FoliageInstance& instance, FoliageType& type, Model* model, int32 lod, float lodDitherFactor, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const;
|
||||||
void DrawCluster(RenderContext& renderContext, FoliageCluster* cluster, FoliageType& type, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const;
|
void DrawCluster(RenderContext& renderContext, FoliageCluster* cluster, FoliageType& type, DrawCallsList* drawCallsLists, BatchedDrawCalls& result) const;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -31,6 +31,14 @@ namespace
|
|||||||
Array<uint64> SortingKeys[2];
|
Array<uint64> SortingKeys[2];
|
||||||
Array<int32> SortingIndices;
|
Array<int32> SortingIndices;
|
||||||
Array<RenderList*> FreeRenderList;
|
Array<RenderList*> FreeRenderList;
|
||||||
|
|
||||||
|
struct MemPoolEntry
|
||||||
|
{
|
||||||
|
void* Ptr;
|
||||||
|
uintptr Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array<MemPoolEntry> MemPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererDirectionalLightData::SetupLightData(LightData* data, const RenderView& view, bool useShadow) const
|
void RendererDirectionalLightData::SetupLightData(LightData* data, const RenderView& view, bool useShadow) const
|
||||||
@@ -101,6 +109,30 @@ void RendererSkyLightData::SetupLightData(LightData* data, const RenderView& vie
|
|||||||
data->RadiusInv = 1.0f / Radius;
|
data->RadiusInv = 1.0f / Radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* RenderListAllocation::Allocate(uintptr size)
|
||||||
|
{
|
||||||
|
void* result = nullptr;
|
||||||
|
for (int32 i = 0; i < MemPool.Count(); i++)
|
||||||
|
{
|
||||||
|
if (MemPool[i].Size == size)
|
||||||
|
{
|
||||||
|
result = MemPool[i].Ptr;
|
||||||
|
MemPool.RemoveAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
result = Platform::Allocate(size, 16);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderListAllocation::Free(void* ptr, uintptr size)
|
||||||
|
{
|
||||||
|
MemPool.Add({ ptr, size });
|
||||||
|
}
|
||||||
|
|
||||||
RenderList* RenderList::GetFromPool()
|
RenderList* RenderList::GetFromPool()
|
||||||
{
|
{
|
||||||
if (FreeRenderList.HasItems())
|
if (FreeRenderList.HasItems())
|
||||||
@@ -132,6 +164,9 @@ void RenderList::CleanupCache()
|
|||||||
SortingKeys[1].Resize(0);
|
SortingKeys[1].Resize(0);
|
||||||
SortingIndices.Resize(0);
|
SortingIndices.Resize(0);
|
||||||
FreeRenderList.ClearDelete();
|
FreeRenderList.ClearDelete();
|
||||||
|
for (auto& e : MemPool)
|
||||||
|
Platform::Free(e.Ptr);
|
||||||
|
MemPool.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderList::BlendableSettings::operator<(const BlendableSettings& other) const
|
bool RenderList::BlendableSettings::operator<(const BlendableSettings& other) const
|
||||||
|
|||||||
@@ -203,10 +203,91 @@ struct DrawBatch
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RenderListAllocation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void* Allocate(uintptr size);
|
||||||
|
static void Free(void* ptr, uintptr size);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Data
|
||||||
|
{
|
||||||
|
T* _data = nullptr;
|
||||||
|
uintptr _size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FORCE_INLINE Data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE ~Data()
|
||||||
|
{
|
||||||
|
if (_data)
|
||||||
|
RenderListAllocation::Free(_data, _size);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE T* Get()
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE const T* Get() const
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE int32 CalculateCapacityGrow(int32 capacity, int32 minCapacity) const
|
||||||
|
{
|
||||||
|
capacity = capacity ? capacity * 2 : 64;
|
||||||
|
if (capacity < minCapacity)
|
||||||
|
capacity = minCapacity;
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void Allocate(uint64 capacity)
|
||||||
|
{
|
||||||
|
_size = capacity * sizeof(T);
|
||||||
|
_data = (T*)RenderListAllocation::Allocate(_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void Relocate(uint64 capacity, int32 oldCount, int32 newCount)
|
||||||
|
{
|
||||||
|
T* newData = capacity != 0 ? (T*)RenderListAllocation::Allocate(capacity * sizeof(T)) : nullptr;
|
||||||
|
if (oldCount)
|
||||||
|
{
|
||||||
|
if (newCount > 0)
|
||||||
|
Memory::MoveItems(newData, _data, newCount);
|
||||||
|
Memory::DestructItems(_data, oldCount);
|
||||||
|
}
|
||||||
|
if (_data)
|
||||||
|
RenderListAllocation::Free(_data, _size);
|
||||||
|
_data = newData;
|
||||||
|
_size = capacity * sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void Free()
|
||||||
|
{
|
||||||
|
if (_data)
|
||||||
|
{
|
||||||
|
RenderListAllocation::Free(_data, _size);
|
||||||
|
_data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE void Swap(Data& other)
|
||||||
|
{
|
||||||
|
::Swap(_data, other._data);
|
||||||
|
::Swap(_size, other._size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct BatchedDrawCall
|
struct BatchedDrawCall
|
||||||
{
|
{
|
||||||
DrawCall DrawCall;
|
DrawCall DrawCall;
|
||||||
Array<struct InstanceData> Instances;
|
Array<struct InstanceData, RenderListAllocation> Instances;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -579,8 +579,8 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
|||||||
GPUTextureView* localShadowedLightScattering = nullptr;
|
GPUTextureView* localShadowedLightScattering = nullptr;
|
||||||
{
|
{
|
||||||
// Get lights to render
|
// Get lights to render
|
||||||
Array<const RendererPointLightData*> pointLights;
|
Array<const RendererPointLightData*, InlinedAllocation<64, RenderListAllocation>> pointLights;
|
||||||
Array<const RendererSpotLightData*> spotLights;
|
Array<const RendererSpotLightData*, InlinedAllocation<64, RenderListAllocation>> spotLights;
|
||||||
for (int32 i = 0; i < renderContext.List->PointLights.Count(); i++)
|
for (int32 i = 0; i < renderContext.List->PointLights.Count(); i++)
|
||||||
{
|
{
|
||||||
const auto& light = renderContext.List->PointLights[i];
|
const auto& light = renderContext.List->PointLights[i];
|
||||||
|
|||||||
Reference in New Issue
Block a user