Index: source/ps/GameSetup/GameSetup.cpp =================================================================== --- source/ps/GameSetup/GameSetup.cpp +++ source/ps/GameSetup/GameSetup.cpp @@ -355,7 +355,6 @@ { TIMER_BEGIN(L"shutdown Renderer"); g_Renderer.~CRenderer(); - g_VBMan.Shutdown(); TIMER_END(L"shutdown Renderer"); } Index: source/renderer/DecalRData.cpp =================================================================== --- source/renderer/DecalRData.cpp +++ source/renderer/DecalRData.cpp @@ -323,7 +323,7 @@ if (!m_VBDecals || m_VBDecals->m_Count != vertices.size()) { - m_VBDecals = g_VBMan.AllocateChunk( + m_VBDecals = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SDecalVertex), vertices.size(), Renderer::Backend::IBuffer::Type::VERTEX, false); } @@ -365,7 +365,7 @@ // Construct vertex buffer. if (!m_VBDecalsIndices || m_VBDecalsIndices->m_Count != indices.size()) { - m_VBDecalsIndices = g_VBMan.AllocateChunk( + m_VBDecalsIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), indices.size(), Renderer::Backend::IBuffer::Type::INDEX, false); } Index: source/renderer/PatchRData.cpp =================================================================== --- source/renderer/PatchRData.cpp +++ source/renderer/PatchRData.cpp @@ -420,7 +420,7 @@ { // Construct vertex buffer - m_VBBlends = g_VBMan.AllocateChunk( + m_VBBlends = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SBlendVertex), blendVertices.size(), Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::TERRAIN); @@ -430,7 +430,7 @@ for (size_t k = 0; k < blendIndices.size(); ++k) blendIndices[k] += static_cast(m_VBBlends->m_Index); - m_VBBlendIndices = g_VBMan.AllocateChunk( + m_VBBlendIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), blendIndices.size(), Renderer::Backend::IBuffer::Type::INDEX, false, nullptr, CVertexBufferManager::Group::TERRAIN); @@ -634,7 +634,7 @@ ENSURE(indices.size()); // Construct vertex buffer - m_VBBaseIndices = g_VBMan.AllocateChunk( + m_VBBaseIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), indices.size(), Renderer::Backend::IBuffer::Type::INDEX, false, nullptr, CVertexBufferManager::Group::TERRAIN); m_VBBaseIndices->m_Owner->UpdateChunkVertices(m_VBBaseIndices.Get(), &indices[0]); @@ -680,7 +680,7 @@ // upload to vertex buffer if (!m_VBBase) { - m_VBBase = g_VBMan.AllocateChunk( + m_VBBase = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SBaseVertex), vsize * vsize, Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::TERRAIN); @@ -774,7 +774,7 @@ if (!m_VBSides) { - m_VBSides = g_VBMan.AllocateChunk( + m_VBSides = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SSideVertex), sideVertices.size(), Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::DEFAULT); @@ -1536,13 +1536,13 @@ // No vertex buffers if no data generated if (!water_indices.empty()) { - m_VBWater = g_VBMan.AllocateChunk( + m_VBWater = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SWaterVertex), water_vertex_data.size(), Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::WATER); m_VBWater->m_Owner->UpdateChunkVertices(m_VBWater.Get(), &water_vertex_data[0]); - m_VBWaterIndices = g_VBMan.AllocateChunk( + m_VBWaterIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), water_indices.size(), Renderer::Backend::IBuffer::Type::INDEX, false, nullptr, CVertexBufferManager::Group::WATER); @@ -1551,14 +1551,14 @@ if (!water_indices_shore.empty()) { - m_VBWaterShore = g_VBMan.AllocateChunk( + m_VBWaterShore = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SWaterVertex), water_vertex_data_shore.size(), Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::WATER); m_VBWaterShore->m_Owner->UpdateChunkVertices(m_VBWaterShore.Get(), &water_vertex_data_shore[0]); // Construct indices buffer - m_VBWaterIndicesShore = g_VBMan.AllocateChunk( + m_VBWaterIndicesShore = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), water_indices_shore.size(), Renderer::Backend::IBuffer::Type::INDEX, false, nullptr, CVertexBufferManager::Group::WATER); Index: source/renderer/Renderer.h =================================================================== --- source/renderer/Renderer.h +++ source/renderer/Renderer.h @@ -37,6 +37,7 @@ class CShaderManager; class CTextureManager; class CTimeManager; +class CVertexBufferManager; #define g_Renderer CRenderer::GetSingleton() @@ -105,6 +106,8 @@ Stats& GetStats() { return m_Stats; } CTextureManager& GetTextureManager(); + + CVertexBufferManager& GetVertexBufferManager(); CShaderManager& GetShaderManager(); Index: source/renderer/Renderer.cpp =================================================================== --- source/renderer/Renderer.cpp +++ source/renderer/Renderer.cpp @@ -199,13 +199,13 @@ case Row_VBReserved: if (col == 0) return "VB reserved"; - sprintf_s(buf, sizeof(buf), "%lu kB", (unsigned long)g_VBMan.GetBytesReserved() / 1024); + sprintf_s(buf, sizeof(buf), "%lu kB", static_cast(g_Renderer.GetVertexBufferManager().GetBytesReserved() / 1024)); return buf; case Row_VBAllocated: if (col == 0) return "VB allocated"; - sprintf_s(buf, sizeof(buf), "%lu kB", (unsigned long)g_VBMan.GetBytesAllocated() / 1024); + sprintf_s(buf, sizeof(buf), "%lu kB", static_cast(g_Renderer.GetVertexBufferManager().GetBytesAllocated() / 1024)); return buf; case Row_TextureMemory: @@ -262,6 +262,8 @@ /// Texture manager CTextureManager textureManager; + CVertexBufferManager vertexBufferManager; + /// Time manager CTimeManager timeManager; @@ -287,7 +289,7 @@ device(device), deviceCommandContext(device->CreateCommandContext()), IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats), - shaderManager(device), textureManager(g_VFS, false, device), + shaderManager(device), textureManager(g_VFS, false, device), vertexBufferManager(device), postprocManager(device), sceneRenderer(device) { } @@ -847,6 +849,11 @@ CTextureManager& CRenderer::GetTextureManager() { return m->textureManager; +} + +CVertexBufferManager& CRenderer::GetVertexBufferManager() +{ + return m->vertexBufferManager; } CShaderManager& CRenderer::GetShaderManager() Index: source/renderer/TexturedLineRData.cpp =================================================================== --- source/renderer/TexturedLineRData.cpp +++ source/renderer/TexturedLineRData.cpp @@ -31,7 +31,7 @@ #include "simulation2/system/SimContext.h" #include "simulation2/components/ICmpWaterManager.h" -/* Note: this implementation uses g_VBMan directly rather than access it through the nicer VertexArray interface, +/* Note: this implementation uses CVertexBufferManager directly rather than access it through the nicer VertexArray interface, * because it allows you to work with variable amounts of vertices and indices more easily. New code should prefer * to use VertexArray where possible, though. */ @@ -330,7 +330,7 @@ for (const SVertex& vertex : vertices) m_BoundingBox += vertex.m_Position; - m_VB = g_VBMan.AllocateChunk( + m_VB = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SVertex), vertices.size(), Renderer::Backend::IBuffer::Type::VERTEX, false); // Allocation might fail (e.g. due to too many vertices). if (m_VB) @@ -341,7 +341,7 @@ for (size_t k = 0; k < indices.size(); ++k) indices[k] += static_cast(m_VB->m_Index); - m_VBIndices = g_VBMan.AllocateChunk( + m_VBIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), indices.size(), Renderer::Backend::IBuffer::Type::INDEX, false); if (m_VBIndices) m_VBIndices->m_Owner->UpdateChunkVertices(m_VBIndices.Get(), &indices[0]); Index: source/renderer/VertexArray.cpp =================================================================== --- source/renderer/VertexArray.cpp +++ source/renderer/VertexArray.cpp @@ -24,6 +24,7 @@ #include "ps/CLogger.h" #include "graphics/Color.h" #include "graphics/SColor.h" +#include "renderer/Renderer.h" #include "renderer/VertexArray.h" #include "renderer/VertexBuffer.h" #include "renderer/VertexBufferManager.h" @@ -269,7 +270,7 @@ if (!m_VB) { - m_VB = g_VBMan.AllocateChunk( + m_VB = g_Renderer.GetVertexBufferManager().AllocateChunk( m_Stride, m_NumberOfVertices, m_Type, m_Dynamic, m_BackingStore); } Index: source/renderer/VertexBuffer.h =================================================================== --- source/renderer/VertexBuffer.h +++ source/renderer/VertexBuffer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,6 +23,7 @@ #define INCLUDED_VERTEXBUFFER #include "renderer/backend/IBuffer.h" +#include "renderer/backend/IDevice.h" #include "renderer/backend/IDeviceCommandContext.h" #include @@ -82,18 +83,19 @@ private: // Only CVertexBuffer can construct/delete these - // (Other people should use g_VBMan.AllocateChunk) + // (Other people should use g_Renderer.GetVertexBufferManager().AllocateChunk) friend class CVertexBuffer; VBChunk() {} ~VBChunk() {} }; public: - // constructor, destructor CVertexBuffer( + Renderer::Backend::IDevice* device, const char* name, const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const bool dynamic); CVertexBuffer( + Renderer::Backend::IDevice* device, const char* name, const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const bool dynamic, const size_t maximumBufferSize); Index: source/renderer/VertexBuffer.cpp =================================================================== --- source/renderer/VertexBuffer.cpp +++ source/renderer/VertexBuffer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,8 +21,6 @@ #include "lib/sysdep/cpu.h" #include "ps/CLogger.h" -#include "ps/Errors.h" -#include "ps/VideoMode.h" #include "renderer/backend/IDevice.h" #include "renderer/Renderer.h" @@ -37,14 +35,14 @@ constexpr std::size_t MAX_VB_SIZE_BYTES = 4 * 1024 * 1024; CVertexBuffer::CVertexBuffer( - const char* name, const size_t vertexSize, + Renderer::Backend::IDevice* device, const char* name, const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const bool dynamic) - : CVertexBuffer(name, vertexSize, type, dynamic, MAX_VB_SIZE_BYTES) + : CVertexBuffer(device, name, vertexSize, type, dynamic, MAX_VB_SIZE_BYTES) { } CVertexBuffer::CVertexBuffer( - const char* name, const size_t vertexSize, + Renderer::Backend::IDevice* device, const char* name, const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const bool dynamic, const size_t maximumBufferSize) : m_VertexSize(vertexSize), m_HasNeededChunks(false) @@ -66,7 +64,7 @@ // store max/free vertex counts m_MaxVertices = m_FreeVertices = size / vertexSize; - m_Buffer = g_VideoMode.GetBackendDevice()->CreateBuffer( + m_Buffer = device->CreateBuffer( name, type, m_MaxVertices * m_VertexSize, dynamic); // create sole free chunk Index: source/renderer/VertexBufferManager.h =================================================================== --- source/renderer/VertexBufferManager.h +++ source/renderer/VertexBufferManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,6 +34,8 @@ class CVertexBufferManager { public: + CVertexBufferManager(Renderer::Backend::IDevice* device) : m_Device(device) {} + enum class Group : u32 { DEFAULT, @@ -99,15 +101,11 @@ size_t GetBytesReserved() const; size_t GetBytesAllocated() const; - /// Explicit shutdown of the vertex buffer subsystem; releases all currently-allocated buffers. - void Shutdown(); - private: + Renderer::Backend::IDevice* m_Device{nullptr}; /// List of all known vertex buffers std::vector> m_Buffers[static_cast(Group::COUNT)]; }; -extern CVertexBufferManager g_VBMan; - -#endif +#endif // INCLUDED_VERTEXBUFFERMANAGER Index: source/renderer/VertexBufferManager.cpp =================================================================== --- source/renderer/VertexBufferManager.cpp +++ source/renderer/VertexBufferManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2023 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,6 +20,7 @@ #include "VertexBufferManager.h" #include "ps/CLogger.h" +#include "renderer/Renderer.h" #define DUMP_VB_STATS 0 // for debugging @@ -69,8 +70,6 @@ } // anonymous namespace -CVertexBufferManager g_VBMan; - CVertexBufferManager::Handle::Handle(Handle&& other) : m_Chunk(other.m_Chunk) { @@ -101,19 +100,10 @@ if (!IsValid()) return; - g_VBMan.Release(m_Chunk); + g_Renderer.GetVertexBufferManager().Release(m_Chunk); m_Chunk = nullptr; } -// Explicit shutdown of the vertex buffer subsystem. -// This avoids the ordering issues that arise when using destructors of -// global instances. -void CVertexBufferManager::Shutdown() -{ - for (int group = static_cast(Group::DEFAULT); group < static_cast(Group::COUNT); ++group) - m_Buffers[group].clear(); -} - /** * AllocateChunk: try to allocate a buffer of given number of vertices (each of * given size), with the given type, and using the given texture - return null @@ -165,9 +155,9 @@ // got this far; need to allocate a new buffer buffers.emplace_back( group == Group::DEFAULT - ? std::make_unique(bufferName, vertexSize, type, dynamic) + ? std::make_unique(m_Device, bufferName, vertexSize, type, dynamic) // Reduces the buffer size for not so frequent buffers. - : std::make_unique(bufferName, vertexSize, type, dynamic, 1024 * 1024)); + : std::make_unique(m_Device, bufferName, vertexSize, type, dynamic, 1024 * 1024)); result = buffers.back()->Allocate(vertexSize, numberOfVertices, type, dynamic, backingStore); if (!result) Index: source/renderer/WaterManager.cpp =================================================================== --- source/renderer/WaterManager.cpp +++ source/renderer/WaterManager.cpp @@ -647,7 +647,7 @@ } } // Generic indexes, max-length - m_ShoreWavesVBIndices = g_VBMan.AllocateChunk( + m_ShoreWavesVBIndices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(u16), water_indices.size(), Renderer::Backend::IBuffer::Type::INDEX, false, nullptr, CVertexBufferManager::Group::WATER); @@ -876,7 +876,7 @@ } j += width/2-1; - shoreWave->m_VBVertices = g_VBMan.AllocateChunk( + shoreWave->m_VBVertices = g_Renderer.GetVertexBufferManager().AllocateChunk( sizeof(SWavesVertex), vertices.size(), Renderer::Backend::IBuffer::Type::VERTEX, false, nullptr, CVertexBufferManager::Group::WATER);