diff --git a/Source/Engine/Foliage/Foliage.h b/Source/Engine/Foliage/Foliage.h index 87b994016..2c6f1d808 100644 --- a/Source/Engine/Foliage/Foliage.h +++ b/Source/Engine/Foliage/Foliage.h @@ -174,7 +174,7 @@ private: }; typedef Array> DrawCallsList; - typedef Dictionary BatchedDrawCalls; + typedef Dictionary BatchedDrawCalls; 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; #else diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index fb6c64c70..369dcdd73 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -31,6 +31,14 @@ namespace Array SortingKeys[2]; Array SortingIndices; Array FreeRenderList; + + struct MemPoolEntry + { + void* Ptr; + uintptr Size; + }; + + Array MemPool; } 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; } +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() { if (FreeRenderList.HasItems()) @@ -132,6 +164,9 @@ void RenderList::CleanupCache() SortingKeys[1].Resize(0); SortingIndices.Resize(0); FreeRenderList.ClearDelete(); + for (auto& e : MemPool) + Platform::Free(e.Ptr); + MemPool.Clear(); } bool RenderList::BlendableSettings::operator<(const BlendableSettings& other) const diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index efc0c55b7..97f369999 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -203,10 +203,91 @@ struct DrawBatch } }; +class RenderListAllocation +{ +public: + + static void* Allocate(uintptr size); + static void Free(void* ptr, uintptr size); + + template + 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 { DrawCall DrawCall; - Array Instances; + Array Instances; }; /// diff --git a/Source/Engine/Renderer/VolumetricFogPass.cpp b/Source/Engine/Renderer/VolumetricFogPass.cpp index 7d7878e6f..2a2322ea8 100644 --- a/Source/Engine/Renderer/VolumetricFogPass.cpp +++ b/Source/Engine/Renderer/VolumetricFogPass.cpp @@ -579,8 +579,8 @@ void VolumetricFogPass::Render(RenderContext& renderContext) GPUTextureView* localShadowedLightScattering = nullptr; { // Get lights to render - Array pointLights; - Array spotLights; + Array> pointLights; + Array> spotLights; for (int32 i = 0; i < renderContext.List->PointLights.Count(); i++) { const auto& light = renderContext.List->PointLights[i];