Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/renderer/VertexBufferManager.cpp
/* Copyright (C) 2021 Wildfire Games. | /* Copyright (C) 2022 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
* GNU General Public License for more details. | * GNU General Public License for more details. | ||||
* | * | ||||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
/* | |||||
* Allocate and destroy CVertexBuffers | |||||
*/ | |||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "VertexBufferManager.h" | #include "VertexBufferManager.h" | ||||
#include "lib/ogl.h" | #include "lib/ogl.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#define DUMP_VB_STATS 0 // for debugging | #define DUMP_VB_STATS 0 // for debugging | ||||
Show All 38 Lines | |||||
// This avoids the ordering issues that arise when using destructors of | // This avoids the ordering issues that arise when using destructors of | ||||
// global instances. | // global instances. | ||||
void CVertexBufferManager::Shutdown() | void CVertexBufferManager::Shutdown() | ||||
{ | { | ||||
for (int group = static_cast<int>(Group::DEFAULT); group < static_cast<int>(Group::COUNT); ++group) | for (int group = static_cast<int>(Group::DEFAULT); group < static_cast<int>(Group::COUNT); ++group) | ||||
m_Buffers[group].clear(); | m_Buffers[group].clear(); | ||||
} | } | ||||
CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore) | /** | ||||
{ | * AllocateChunk: try to allocate a buffer of given number of vertices (each of | ||||
return AllocateImpl(vertexSize, numVertices, usage, target, backingStore, Group::DEFAULT); | * given size), with the given type, and using the given texture - return null | ||||
} | * if no free chunks available | ||||
*/ | |||||
CVertexBufferManager::Handle CVertexBufferManager::AllocateChunk(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore, Group group) | CVertexBufferManager::Handle CVertexBufferManager::AllocateChunk(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore, Group group) | ||||
{ | { | ||||
CVertexBuffer::VBChunk* chunk = AllocateImpl(vertexSize, numVertices, usage, target, backingStore, group); | |||||
if (!chunk) | |||||
return Handle(); | |||||
return Handle(chunk); | |||||
} | |||||
// Allocate: 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 | |||||
// if no free chunks available | |||||
CVertexBuffer::VBChunk* CVertexBufferManager::AllocateImpl(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target, void* backingStore, Group group) | |||||
{ | |||||
CVertexBuffer::VBChunk* result = nullptr; | CVertexBuffer::VBChunk* result = nullptr; | ||||
ENSURE(usage == GL_STREAM_DRAW || usage == GL_STATIC_DRAW || usage == GL_DYNAMIC_DRAW); | ENSURE(usage == GL_STREAM_DRAW || usage == GL_STATIC_DRAW || usage == GL_DYNAMIC_DRAW); | ||||
ENSURE(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); | ENSURE(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); | ||||
if (CVertexBuffer::UseStreaming(usage)) | if (CVertexBuffer::UseStreaming(usage)) | ||||
ENSURE(backingStore != NULL); | ENSURE(backingStore != NULL); | ||||
Show All 15 Lines | |||||
#endif | #endif | ||||
// iterate through all existing buffers testing for one that'll | // iterate through all existing buffers testing for one that'll | ||||
// satisfy the allocation | // satisfy the allocation | ||||
for (const std::unique_ptr<CVertexBuffer>& buffer : buffers) | for (const std::unique_ptr<CVertexBuffer>& buffer : buffers) | ||||
{ | { | ||||
result = buffer->Allocate(vertexSize, numVertices, usage, target, backingStore); | result = buffer->Allocate(vertexSize, numVertices, usage, target, backingStore); | ||||
if (result) | if (result) | ||||
return result; | return Handle(result); | ||||
} | } | ||||
// got this far; need to allocate a new buffer | // got this far; need to allocate a new buffer | ||||
buffers.emplace_back( | buffers.emplace_back( | ||||
group == Group::DEFAULT | group == Group::DEFAULT | ||||
? std::make_unique<CVertexBuffer>(vertexSize, usage, target) | ? std::make_unique<CVertexBuffer>(vertexSize, usage, target) | ||||
// Reduces the buffer size for not so frequent buffers. | // Reduces the buffer size for not so frequent buffers. | ||||
: std::make_unique<CVertexBuffer>(vertexSize, usage, target, 1024 * 1024)); | : std::make_unique<CVertexBuffer>(vertexSize, usage, target, 1024 * 1024)); | ||||
result = buffers.back()->Allocate(vertexSize, numVertices, usage, target, backingStore); | result = buffers.back()->Allocate(vertexSize, numVertices, usage, target, backingStore); | ||||
if (!result) | if (!result) | ||||
{ | { | ||||
LOGERROR("Failed to create VBOs (%zu*%zu)", vertexSize, numVertices); | LOGERROR("Failed to create VBOs (%zu*%zu)", vertexSize, numVertices); | ||||
return Handle(); | |||||
} | } | ||||
return result; | return Handle(result); | ||||
} | } | ||||
void CVertexBufferManager::Release(CVertexBuffer::VBChunk* chunk) | void CVertexBufferManager::Release(CVertexBuffer::VBChunk* chunk) | ||||
{ | { | ||||
ENSURE(chunk); | ENSURE(chunk); | ||||
#if DUMP_VB_STATS | #if DUMP_VB_STATS | ||||
debug_printf("\n============================\n# release %p nverts=%zu\n\n", chunk, chunk->m_Count); | debug_printf("\n============================\n# release %p nverts=%zu\n\n", chunk, chunk->m_Count); | ||||
#endif | #endif | ||||
Show All 20 Lines |
Wildfire Games · Phabricator