forked from mirrors/0ad
Makes TextRenderer allocates using LinearAllocator
Also replaces DynamicArena for model and terrain rendering by LinearAllocator.
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "lib/alignment.h"
|
||||
#include "lib/allocators/DynamicArena.h"
|
||||
#include "lib/allocators/STLAllocators.h"
|
||||
#include "lib/debug.h"
|
||||
#include "lib/posix/posix_types.h"
|
||||
@@ -38,6 +37,7 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStrIntern.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/memory/LinearAllocator.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/Renderer.h"
|
||||
#include "renderer/TerrainRenderer.h"
|
||||
@@ -143,12 +143,10 @@ void CDecalRData::RenderDecals(
|
||||
PROFILE3("render terrain decals");
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain decals");
|
||||
|
||||
using Arena = Allocators::DynamicArena<256 * KiB>;
|
||||
PS::Memory::ScopedLinearAllocator scopedLinearAllocator{g_Renderer.GetLinearAllocator()};
|
||||
|
||||
Arena arena;
|
||||
|
||||
using Batches = std::vector<SDecalBatch, ProxyAllocator<SDecalBatch, Arena>>;
|
||||
Batches batches((Batches::allocator_type(arena)));
|
||||
using Batches = std::vector<SDecalBatch, ProxyAllocator<SDecalBatch, PS::Memory::ScopedLinearAllocator>>;
|
||||
Batches batches((Batches::allocator_type(scopedLinearAllocator)));
|
||||
batches.reserve(decals.size());
|
||||
|
||||
CShaderDefines contextDecal = context;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "graphics/Texture.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "lib/alignment.h"
|
||||
#include "lib/allocators/DynamicArena.h"
|
||||
#include "lib/allocators/STLAllocators.h"
|
||||
#include "lib/debug.h"
|
||||
#include "lib/hash.h"
|
||||
@@ -41,6 +40,7 @@
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStrIntern.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/memory/LinearAllocator.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/MikktspaceWrap.h"
|
||||
#include "renderer/ModelRenderer.h"
|
||||
@@ -441,10 +441,9 @@ void ShaderModelRenderer::Render(
|
||||
* list in each, rebinding the GL state whenever it changes.
|
||||
*/
|
||||
|
||||
using Arena = Allocators::DynamicArena<256 * KiB>;
|
||||
PS::Memory::ScopedLinearAllocator scopedLinearAllocator{g_Renderer.GetLinearAllocator()};
|
||||
|
||||
Arena arena;
|
||||
using ModelListAllocator = ProxyAllocator<CModel*, Arena>;
|
||||
using ModelListAllocator = ProxyAllocator<CModel*, PS::Memory::ScopedLinearAllocator>;
|
||||
using ModelList_t = std::vector<CModel*, ModelListAllocator>;
|
||||
using MaterialBuckets_t = std::unordered_map<
|
||||
SMRMaterialBucketKey,
|
||||
@@ -453,9 +452,9 @@ void ShaderModelRenderer::Render(
|
||||
std::equal_to<SMRMaterialBucketKey>,
|
||||
ProxyAllocator<
|
||||
std::pair<const SMRMaterialBucketKey, ModelList_t>,
|
||||
Arena> >;
|
||||
PS::Memory::ScopedLinearAllocator>>;
|
||||
|
||||
MaterialBuckets_t materialBuckets((MaterialBuckets_t::allocator_type(arena)));
|
||||
MaterialBuckets_t materialBuckets((MaterialBuckets_t::allocator_type(scopedLinearAllocator)));
|
||||
|
||||
{
|
||||
PROFILE3("bucketing by material");
|
||||
@@ -470,7 +469,7 @@ void ShaderModelRenderer::Render(
|
||||
if (it == materialBuckets.end())
|
||||
{
|
||||
std::pair<MaterialBuckets_t::iterator, bool> inserted = materialBuckets.insert(
|
||||
std::make_pair(key, ModelList_t(ModelList_t::allocator_type(arena))));
|
||||
std::make_pair(key, ModelList_t(ModelList_t::allocator_type(scopedLinearAllocator))));
|
||||
inserted.first->second.reserve(32);
|
||||
inserted.first->second.push_back(model);
|
||||
}
|
||||
@@ -481,19 +480,19 @@ void ShaderModelRenderer::Render(
|
||||
}
|
||||
}
|
||||
|
||||
using SortByDistItemsAllocator = ProxyAllocator<SMRSortByDistItem, Arena>;
|
||||
std::vector<SMRSortByDistItem, SortByDistItemsAllocator> sortByDistItems((SortByDistItemsAllocator(arena)));
|
||||
using SortByDistItemsAllocator = ProxyAllocator<SMRSortByDistItem, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<SMRSortByDistItem, SortByDistItemsAllocator> sortByDistItems((SortByDistItemsAllocator(scopedLinearAllocator)));
|
||||
|
||||
using SortByTechItemsAllocator = ProxyAllocator<CShaderTechniquePtr, Arena>;
|
||||
std::vector<CShaderTechniquePtr, SortByTechItemsAllocator> sortByDistTechs((SortByTechItemsAllocator(arena)));
|
||||
using SortByTechItemsAllocator = ProxyAllocator<CShaderTechniquePtr, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<CShaderTechniquePtr, SortByTechItemsAllocator> sortByDistTechs((SortByTechItemsAllocator(scopedLinearAllocator)));
|
||||
// indexed by sortByDistItems[i].techIdx
|
||||
// (which stores indexes instead of CShaderTechniquePtr directly
|
||||
// to avoid the shared_ptr copy cost when sorting; maybe it'd be better
|
||||
// if we just stored raw CShaderTechnique* and assumed the shader manager
|
||||
// will keep it alive long enough)
|
||||
|
||||
using TechBucketsAllocator = ProxyAllocator<SMRTechBucket, Arena>;
|
||||
std::vector<SMRTechBucket, TechBucketsAllocator> techBuckets((TechBucketsAllocator(arena)));
|
||||
using TechBucketsAllocator = ProxyAllocator<SMRTechBucket, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<SMRTechBucket, TechBucketsAllocator> techBuckets((TechBucketsAllocator(scopedLinearAllocator)));
|
||||
|
||||
{
|
||||
PROFILE3("processing material buckets");
|
||||
@@ -555,7 +554,7 @@ void ShaderModelRenderer::Render(
|
||||
// (This exists primarily because techBuckets wants a CModel**;
|
||||
// we could avoid the cost of copying into this list by adding
|
||||
// a stride length into techBuckets and not requiring contiguous CModel*s)
|
||||
std::vector<CModel*, ModelListAllocator> sortByDistModels((ModelListAllocator(arena)));
|
||||
std::vector<CModel*, ModelListAllocator> sortByDistModels((ModelListAllocator(scopedLinearAllocator)));
|
||||
|
||||
if (!sortByDistItems.empty())
|
||||
{
|
||||
@@ -608,19 +607,19 @@ void ShaderModelRenderer::Render(
|
||||
// This vector keeps track of texture changes during rendering. It is kept outside the
|
||||
// loops to avoid excessive reallocations. The token allocation of 64 elements
|
||||
// should be plenty, though it is reallocated below (at a cost) if necessary.
|
||||
using TextureListAllocator = ProxyAllocator<CTexture*, Arena>;
|
||||
std::vector<CTexture*, TextureListAllocator> currentTexs((TextureListAllocator(arena)));
|
||||
using TextureListAllocator = ProxyAllocator<CTexture*, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<CTexture*, TextureListAllocator> currentTexs((TextureListAllocator(scopedLinearAllocator)));
|
||||
currentTexs.reserve(64);
|
||||
|
||||
// texBindings holds the identifier bindings in the shader, which can no longer be defined
|
||||
// statically in the ShaderRenderModifier class. texBindingNames uses interned strings to
|
||||
// keep track of when bindings need to be reevaluated.
|
||||
using BindingListAllocator = ProxyAllocator<int32_t, Arena>;
|
||||
std::vector<int32_t, BindingListAllocator> texBindings((BindingListAllocator(arena)));
|
||||
using BindingListAllocator = ProxyAllocator<int32_t, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<int32_t, BindingListAllocator> texBindings((BindingListAllocator(scopedLinearAllocator)));
|
||||
texBindings.reserve(64);
|
||||
|
||||
using BindingNamesListAllocator = ProxyAllocator<CStrIntern, Arena>;
|
||||
std::vector<CStrIntern, BindingNamesListAllocator> texBindingNames((BindingNamesListAllocator(arena)));
|
||||
using BindingNamesListAllocator = ProxyAllocator<CStrIntern, PS::Memory::ScopedLinearAllocator>;
|
||||
std::vector<CStrIntern, BindingNamesListAllocator> texBindingNames((BindingNamesListAllocator(scopedLinearAllocator)));
|
||||
texBindingNames.reserve(64);
|
||||
|
||||
while (idxTechStart < techBuckets.size())
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "graphics/TextRenderer.h"
|
||||
#include "graphics/TextureManager.h"
|
||||
#include "lib/alignment.h"
|
||||
#include "lib/allocators/DynamicArena.h"
|
||||
#include "lib/allocators/STLAllocators.h"
|
||||
#include "lib/code_generation.h"
|
||||
#include "lib/debug.h"
|
||||
@@ -45,6 +44,7 @@
|
||||
#include "ps/CStrIntern.h"
|
||||
#include "ps/CStrInternStatic.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/memory/LinearAllocator.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "renderer/AlphaMapCalculator.h"
|
||||
#include "renderer/BlendShapes.h"
|
||||
@@ -841,16 +841,14 @@ void CPatchRData::Update(CSimulation2* simulation)
|
||||
// batches uses a arena allocator. (All allocations are short-lived so we can
|
||||
// just throw away the whole arena at the end of each frame.)
|
||||
|
||||
using Arena = Allocators::DynamicArena<1 * MiB>;
|
||||
|
||||
// std::map types with appropriate arena allocators and default comparison operator
|
||||
template<class Key, class Value>
|
||||
using PooledBatchMap = std::map<Key, Value, std::less<Key>, ProxyAllocator<std::pair<Key const, Value>, Arena>>;
|
||||
using PooledBatchMap = std::map<Key, Value, std::less<Key>, ProxyAllocator<std::pair<Key const, Value>, PS::Memory::ScopedLinearAllocator>>;
|
||||
|
||||
// Equivalent to "m[k]", when it returns a arena-allocated std::map (since we can't
|
||||
// use the default constructor in that case)
|
||||
template<typename M>
|
||||
typename M::mapped_type& PooledMapGet(M& m, const typename M::key_type& k, Arena& arena)
|
||||
typename M::mapped_type& PooledMapGet(M& m, const typename M::key_type& k, PS::Memory::ScopedLinearAllocator& arena)
|
||||
{
|
||||
return m.insert(std::make_pair(k,
|
||||
typename M::mapped_type(typename M::mapped_type::key_compare(), typename M::mapped_type::allocator_type(arena))
|
||||
@@ -859,7 +857,7 @@ typename M::mapped_type& PooledMapGet(M& m, const typename M::key_type& k, Arena
|
||||
|
||||
// Equivalent to "m[k]", when it returns a std::pair of arena-allocated std::vectors
|
||||
template<typename M>
|
||||
typename M::mapped_type& PooledPairGet(M& m, const typename M::key_type& k, Arena& arena)
|
||||
typename M::mapped_type& PooledPairGet(M& m, const typename M::key_type& k, PS::Memory::ScopedLinearAllocator& arena)
|
||||
{
|
||||
return m.insert(std::make_pair(k, std::make_pair(
|
||||
typename M::mapped_type::first_type(typename M::mapped_type::first_type::allocator_type(arena)),
|
||||
@@ -868,7 +866,7 @@ typename M::mapped_type& PooledPairGet(M& m, const typename M::key_type& k, Aren
|
||||
}
|
||||
|
||||
// Each multidraw batch has a list of index counts, and a list of pointers-to-first-indexes
|
||||
using BatchElements = std::pair<std::vector<u32, ProxyAllocator<u32, Arena>>, std::vector<u32, ProxyAllocator<u32, Arena>>>;
|
||||
using BatchElements = std::pair<std::vector<u32, ProxyAllocator<u32, PS::Memory::ScopedLinearAllocator>>, std::vector<u32, ProxyAllocator<u32, PS::Memory::ScopedLinearAllocator>>>;
|
||||
|
||||
// Group batches by index buffer
|
||||
using IndexBufferBatches = PooledBatchMap<CVertexBuffer*, BatchElements>;
|
||||
@@ -890,9 +888,9 @@ void CPatchRData::RenderBases(
|
||||
PROFILE3("render terrain bases");
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain bases");
|
||||
|
||||
Arena arena;
|
||||
PS::Memory::ScopedLinearAllocator scopedLinearAllocator{g_Renderer.GetLinearAllocator()};
|
||||
|
||||
ShaderTechniqueBatches batches(ShaderTechniqueBatches::key_compare(), (ShaderTechniqueBatches::allocator_type(arena)));
|
||||
ShaderTechniqueBatches batches(ShaderTechniqueBatches::key_compare(), (ShaderTechniqueBatches::allocator_type(scopedLinearAllocator)));
|
||||
|
||||
PROFILE_START("compute batches");
|
||||
|
||||
@@ -913,12 +911,12 @@ void CPatchRData::RenderBases(
|
||||
BatchElements& batch = PooledPairGet(
|
||||
PooledMapGet(
|
||||
PooledMapGet(
|
||||
PooledMapGet(batches, std::make_pair(material.GetShaderEffect(), material.GetShaderDefines()), arena),
|
||||
splat.m_Texture, arena
|
||||
PooledMapGet(batches, std::make_pair(material.GetShaderEffect(), material.GetShaderDefines()), scopedLinearAllocator),
|
||||
splat.m_Texture, scopedLinearAllocator
|
||||
),
|
||||
patch->m_VBBase->m_Owner, arena
|
||||
patch->m_VBBase->m_Owner, scopedLinearAllocator
|
||||
),
|
||||
patch->m_VBBaseIndices->m_Owner, arena
|
||||
patch->m_VBBaseIndices->m_Owner, scopedLinearAllocator
|
||||
);
|
||||
|
||||
batch.first.push_back(splat.m_IndexCount);
|
||||
@@ -1015,8 +1013,8 @@ void CPatchRData::RenderBases(
|
||||
*/
|
||||
struct SBlendBatch
|
||||
{
|
||||
SBlendBatch(Arena& arena) :
|
||||
m_Batches(VertexBufferBatches::key_compare(), VertexBufferBatches::allocator_type(arena))
|
||||
SBlendBatch(PS::Memory::ScopedLinearAllocator& allocator) :
|
||||
m_Batches(VertexBufferBatches::key_compare(), VertexBufferBatches::allocator_type(allocator))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1031,12 +1029,12 @@ struct SBlendBatch
|
||||
struct SBlendStackItem
|
||||
{
|
||||
SBlendStackItem(CVertexBuffer::VBChunk* v, CVertexBuffer::VBChunk* i,
|
||||
const std::vector<CPatchRData::SSplat>& s, Arena& arena) :
|
||||
vertices(v), indices(i), splats(s.begin(), s.end(), SplatStack::allocator_type(arena))
|
||||
const std::vector<CPatchRData::SSplat>& s, PS::Memory::ScopedLinearAllocator& allocator) :
|
||||
vertices(v), indices(i), splats(s.begin(), s.end(), SplatStack::allocator_type(allocator))
|
||||
{
|
||||
}
|
||||
|
||||
using SplatStack = std::vector<CPatchRData::SSplat, ProxyAllocator<CPatchRData::SSplat, Arena>>;
|
||||
using SplatStack = std::vector<CPatchRData::SSplat, ProxyAllocator<CPatchRData::SSplat, PS::Memory::ScopedLinearAllocator>>;
|
||||
CVertexBuffer::VBChunk* vertices;
|
||||
CVertexBuffer::VBChunk* indices;
|
||||
SplatStack splats;
|
||||
@@ -1050,10 +1048,10 @@ void CPatchRData::RenderBlends(
|
||||
PROFILE3("render terrain blends");
|
||||
GPU_SCOPED_LABEL(deviceCommandContext, "Render terrain blends");
|
||||
|
||||
Arena arena;
|
||||
PS::Memory::ScopedLinearAllocator scopedLinearAllocator{g_Renderer.GetLinearAllocator()};
|
||||
|
||||
using BatchesStack = std::vector<SBlendBatch, ProxyAllocator<SBlendBatch, Arena>>;
|
||||
BatchesStack batches((BatchesStack::allocator_type(arena)));
|
||||
using BatchesStack = std::vector<SBlendBatch, ProxyAllocator<SBlendBatch, PS::Memory::ScopedLinearAllocator>>;
|
||||
BatchesStack batches((BatchesStack::allocator_type(scopedLinearAllocator)));
|
||||
|
||||
CShaderDefines contextBlend = context;
|
||||
contextBlend.Add(str_BLEND, str_1);
|
||||
@@ -1064,8 +1062,8 @@ void CPatchRData::RenderBlends(
|
||||
// to avoid heavy reallocations
|
||||
batches.reserve(256);
|
||||
|
||||
using BlendStacks = std::vector<SBlendStackItem, ProxyAllocator<SBlendStackItem, Arena>>;
|
||||
BlendStacks blendStacks((BlendStacks::allocator_type(arena)));
|
||||
using BlendStacks = std::vector<SBlendStackItem, ProxyAllocator<SBlendStackItem, PS::Memory::ScopedLinearAllocator>>;
|
||||
BlendStacks blendStacks((BlendStacks::allocator_type(scopedLinearAllocator)));
|
||||
blendStacks.reserve(patches.size());
|
||||
|
||||
// Extract all the blend splats from each patch
|
||||
@@ -1074,8 +1072,7 @@ void CPatchRData::RenderBlends(
|
||||
CPatchRData* patch = patches[i];
|
||||
if (!patch->m_BlendSplats.empty())
|
||||
{
|
||||
|
||||
blendStacks.push_back(SBlendStackItem(patch->m_VBBlends.Get(), patch->m_VBBlendIndices.Get(), patch->m_BlendSplats, arena));
|
||||
blendStacks.push_back(SBlendStackItem(patch->m_VBBlends.Get(), patch->m_VBBlendIndices.Get(), patch->m_BlendSplats, scopedLinearAllocator));
|
||||
// Reverse the splats so the first to be rendered is at the back of the list
|
||||
std::reverse(blendStacks.back().splats.begin(), blendStacks.back().splats.end());
|
||||
}
|
||||
@@ -1100,7 +1097,7 @@ void CPatchRData::RenderBlends(
|
||||
CVertexBuffer::VBChunk* vertices = blendStacks[k].vertices;
|
||||
CVertexBuffer::VBChunk* indices = blendStacks[k].indices;
|
||||
|
||||
BatchElements& batch = PooledPairGet(PooledMapGet(batches.back().m_Batches, vertices->m_Owner, arena), indices->m_Owner, arena);
|
||||
BatchElements& batch = PooledPairGet(PooledMapGet(batches.back().m_Batches, vertices->m_Owner, scopedLinearAllocator), indices->m_Owner, scopedLinearAllocator);
|
||||
batch.first.push_back(splats.back().m_IndexCount);
|
||||
|
||||
batch.second.push_back(indices->m_Index + splats.back().m_IndexStart);
|
||||
@@ -1126,7 +1123,7 @@ void CPatchRData::RenderBlends(
|
||||
if (bestStackSize == 0)
|
||||
break;
|
||||
|
||||
SBlendBatch layer(arena);
|
||||
SBlendBatch layer(scopedLinearAllocator);
|
||||
layer.m_Texture = bestTex;
|
||||
if (!bestTex->GetMaterial().GetSamplers().empty())
|
||||
{
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/GameSetup/Config.h"
|
||||
#include "ps/Globals.h"
|
||||
#include "ps/memory/LinearAllocator.h"
|
||||
#include "ps/Profile.h"
|
||||
#include "ps/ProfileViewer.h"
|
||||
#include "ps/Profiler2.h"
|
||||
@@ -99,7 +100,7 @@ class CRendererStatsTable : public AbstractProfileTable
|
||||
{
|
||||
NONCOPYABLE(CRendererStatsTable);
|
||||
public:
|
||||
CRendererStatsTable(const CRenderer::Stats& st);
|
||||
CRendererStatsTable(const CRenderer::Stats& st, const PS::Memory::LinearAllocator& linearAllocator);
|
||||
|
||||
// Implementation of AbstractProfileTable interface
|
||||
CStr GetName() override;
|
||||
@@ -112,6 +113,7 @@ public:
|
||||
private:
|
||||
/// Reference to the renderer singleton's stats
|
||||
const CRenderer::Stats& Stats;
|
||||
const PS::Memory::LinearAllocator& m_LinearAllocator;
|
||||
|
||||
/// Column descriptions
|
||||
std::vector<ProfileColumn> columnDescriptions;
|
||||
@@ -129,6 +131,7 @@ private:
|
||||
Row_VBAllocated,
|
||||
Row_TextureMemory,
|
||||
Row_ShadersLoaded,
|
||||
Row_LinearAllocator,
|
||||
|
||||
// Must be last to count number of rows
|
||||
NumberRows
|
||||
@@ -136,8 +139,8 @@ private:
|
||||
};
|
||||
|
||||
// Construction
|
||||
CRendererStatsTable::CRendererStatsTable(const CRenderer::Stats& st)
|
||||
: Stats(st)
|
||||
CRendererStatsTable::CRendererStatsTable(const CRenderer::Stats& st, const PS::Memory::LinearAllocator& linearAllocator)
|
||||
: Stats(st), m_LinearAllocator(linearAllocator)
|
||||
{
|
||||
columnDescriptions.push_back(ProfileColumn("Name", 230));
|
||||
columnDescriptions.push_back(ProfileColumn("Value", 100));
|
||||
@@ -236,6 +239,12 @@ CStr CRendererStatsTable::GetCellText(size_t row, size_t col)
|
||||
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)g_Renderer.GetShaderManager().GetNumEffectsLoaded());
|
||||
return buf;
|
||||
|
||||
case Row_LinearAllocator:
|
||||
if (col == 0)
|
||||
return "linear allocator";
|
||||
sprintf_s(buf, sizeof(buf), "%lu", static_cast<unsigned long>(m_LinearAllocator.GetCapacity()));
|
||||
return buf;
|
||||
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
@@ -292,6 +301,13 @@ public:
|
||||
|
||||
CFontManager fontManager;
|
||||
|
||||
// During rendering we need to collect and sort many objects. To reduce
|
||||
// the allocation cost and increase cache locality we use the
|
||||
// LinearAllocator.
|
||||
// If we need to have more than 16MiB of continious memory then we're doing
|
||||
// a lot of unnecessary work.
|
||||
PS::Memory::LinearAllocator linearAllocator{1 * MiB, 16 * MiB};
|
||||
|
||||
struct VertexAttributesHash
|
||||
{
|
||||
size_t operator()(const std::vector<Renderer::Backend::SVertexAttributeFormat>& attributes) const;
|
||||
@@ -304,7 +320,7 @@ public:
|
||||
Internals(Renderer::Backend::IDevice* device) :
|
||||
device(device),
|
||||
deviceCommandContext(device->CreateCommandContext()),
|
||||
IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats),
|
||||
IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats, linearAllocator),
|
||||
shaderManager(device), textureManager(g_VFS, false, device), vertexBufferManager(device),
|
||||
postprocManager(device), sceneRenderer(device)
|
||||
{
|
||||
@@ -623,6 +639,8 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
|
||||
PROFILE2_ATTR("particles: %zu", stats.m_Particles);
|
||||
|
||||
g_Profiler2.RecordGPUFrameEnd(m->deviceCommandContext.get());
|
||||
|
||||
m->linearAllocator.Release();
|
||||
}
|
||||
|
||||
void CRenderer::RenderFrame2D(const bool renderGUI, const bool renderLogger)
|
||||
@@ -858,6 +876,8 @@ void CRenderer::EndFrame()
|
||||
PROFILE3("end frame");
|
||||
|
||||
m->sceneRenderer.EndFrame();
|
||||
|
||||
m->linearAllocator.Release();
|
||||
}
|
||||
|
||||
void CRenderer::MakeShadersDirty()
|
||||
@@ -930,3 +950,8 @@ Renderer::Backend::IVertexInputLayout* CRenderer::GetVertexInputLayout(
|
||||
it->second = m->device->CreateVertexInputLayout(attributes);
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
PS::Memory::LinearAllocator& CRenderer::GetLinearAllocator()
|
||||
{
|
||||
return m->linearAllocator;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class CShaderManager;
|
||||
class CTextureManager;
|
||||
class CTimeManager;
|
||||
class CVertexBufferManager;
|
||||
namespace PS::Memory { class LinearAllocator; }
|
||||
namespace Renderer::Backend { class IDevice; }
|
||||
namespace Renderer::Backend { class IDeviceCommandContext; }
|
||||
namespace Renderer::Backend { class IVertexInputLayout; }
|
||||
@@ -144,6 +145,12 @@ public:
|
||||
Renderer::Backend::IVertexInputLayout* GetVertexInputLayout(
|
||||
const std::span<const Renderer::Backend::SVertexAttributeFormat> attributes);
|
||||
|
||||
/**
|
||||
* Currently using the linear allocated is allowed in small scopes to avoid
|
||||
* high memory overhead. To validate that use PS::Memory::ScopedLinearAllocator.
|
||||
*/
|
||||
PS::Memory::LinearAllocator& GetLinearAllocator();
|
||||
|
||||
protected:
|
||||
friend class CDecalRData;
|
||||
friend class CPatchRData;
|
||||
|
||||
Reference in New Issue
Block a user