Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
VertexBuffer.h
Go to the documentation of this file.
1/* Copyright (C) 2024 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Encapsulation of backend buffers with batching and sharing.
20 */
21
22#ifndef INCLUDED_VERTEXBUFFER
23#define INCLUDED_VERTEXBUFFER
24
28
29#include <memory>
30#include <vector>
31
32/**
33 * CVertexBuffer: encapsulation of backend buffers, also supplying
34 * some additional functionality for sharing buffers between multiple objects.
35 *
36 * The class can be used in two modes, depending on the usage parameter:
37 *
38 * Static buffer: Call Allocate() with backingStore = nullptr. Then call
39 * UpdateChunkVertices() with any pointer - the data will be immediately copied
40 * to the buffer. This should be used for vertex data that rarely changes.
41 *
42 * Dynamic buffer: Call Allocate() with backingStore pointing
43 * at some memory that will remain valid for the lifetime of the CVertexBuffer.
44 * This should be used for vertex data that may change every frame.
45 * Rendering is expected to occur in two phases:
46 * - "Prepare" phase:
47 * If this chunk is going to be used for rendering during the next rendering phase,
48 * you must call PrepareForRendering().
49 * If the vertex data in backingStore has been modified since the last uploading phase,
50 * you must call UpdateChunkVertices().
51 * - "Upload" phase:
52 * UploadedIfNeeded() can be called (multiple times). The vertex data will be uploaded
53 * to the GPU if necessary.
54 * It is okay to have multiple prepare/upload cycles per frame (though slightly less
55 * efficient), but they must occur sequentially.
56 */
58{
60
61public:
62
63 // VBChunk: describes a portion of this vertex buffer
64 struct VBChunk
65 {
66 // Owning (parent) vertex buffer
68 // Start index of this chunk in owner
69 size_t m_Index;
70 // Number of vertices used by chunk
71 size_t m_Count;
72 // If UseStreaming() is true, points at the data for this chunk
74
75 // If true, the backend buffer is not consistent with the chunk's
76 // backing store (and will need to be re-uploaded before rendering with
77 // this chunk).
78 bool m_Dirty;
79
80 // If true, we have been told this chunk is going to be used for
81 // rendering in the next uploading phase and will need to be uploaded
83
84 private:
85 // Only CVertexBuffer can construct/delete these
86 // (Other people should use g_Renderer.GetVertexBufferManager().AllocateChunk)
87 friend class CVertexBuffer;
90 };
91
92public:
95 const char* name, const size_t vertexSize,
96 const Renderer::Backend::IBuffer::Type type, const uint32_t usage);
99 const char* name, const size_t vertexSize,
100 const Renderer::Backend::IBuffer::Type type, const uint32_t usage,
101 const size_t maximumBufferSize);
103
105
106 /// Make the vertex data available for the next usage.
107 void PrepareForRendering(VBChunk* chunk);
108
109 /// Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer.
110 void UpdateChunkVertices(VBChunk* chunk, void* data);
111
112 size_t GetVertexSize() const { return m_VertexSize; }
113 size_t GetBytesReserved() const;
114 size_t GetBytesAllocated() const;
115
116 /// Returns true if this vertex buffer is compatible with the specified vertex type and intended usage.
118 const size_t vertexSize, const Renderer::Backend::IBuffer::Type type,
119 const uint32_t usage) const;
120
121 void DumpStatus() const;
122
123 /**
124 * Given the usage flags of a buffer that has been (or will be) allocated:
125 *
126 * If true, we assume the buffer is going to be modified on every frame,
127 * so we will re-upload the entire buffer every frame using glMapBuffer.
128 * This requires the buffer's owner to hold onto its backing store.
129 *
130 * If false, we assume it will change rarely, and use direct upload to
131 * update it incrementally. The backing store can be freed to save memory.
132 */
133 static bool UseStreaming(const uint32_t usage);
134
136
137private:
138 friend class CVertexBufferManager; // allow allocate only via CVertexBufferManager
139
140 /// Try to allocate a buffer of given number of vertices (each of given size),
141 /// and with the given type - return null if no free chunks available
143 const size_t vertexSize, const size_t numberOfVertices,
144 const Renderer::Backend::IBuffer::Type type, const uint32_t usage,
145 void* backingStore);
146 /// Return given chunk to this buffer
147 void Release(VBChunk* chunk);
148
149 /// Vertex size of this vertex buffer
151 /// Number of vertices of above size in this buffer
153 /// List of free chunks in this buffer
154 std::vector<VBChunk*> m_FreeList;
155 /// List of allocated chunks
156 std::vector<VBChunk*> m_AllocList;
157 /// Available free vertices - total of all free vertices in the free list
159
160 std::unique_ptr<Renderer::Backend::IBuffer> m_Buffer;
161
163};
164
165#endif // INCLUDED_VERTEXBUFFER
Definition: VertexBufferManager.h:35
CVertexBuffer: encapsulation of backend buffers, also supplying some additional functionality for sha...
Definition: VertexBuffer.h:58
size_t m_FreeVertices
Available free vertices - total of all free vertices in the free list.
Definition: VertexBuffer.h:158
~CVertexBuffer()
Definition: VertexBuffer.cpp:78
static bool UseStreaming(const uint32_t usage)
Given the usage flags of a buffer that has been (or will be) allocated:
Definition: VertexBuffer.cpp:313
void UpdateChunkVertices(VBChunk *chunk, void *data)
Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer.
Definition: VertexBuffer.cpp:206
std::vector< VBChunk * > m_FreeList
List of free chunks in this buffer.
Definition: VertexBuffer.h:154
NONCOPYABLE(CVertexBuffer)
void PrepareForRendering(VBChunk *chunk)
Make the vertex data available for the next usage.
Definition: VertexBuffer.cpp:318
CVertexBuffer(Renderer::Backend::IDevice *device, const char *name, const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const uint32_t usage)
Definition: VertexBuffer.cpp:37
size_t GetVertexSize() const
Definition: VertexBuffer.h:112
VBChunk * Allocate(const size_t vertexSize, const size_t numberOfVertices, const Renderer::Backend::IBuffer::Type type, const uint32_t usage, void *backingStore)
Try to allocate a buffer of given number of vertices (each of given size), and with the given type - ...
Definition: VertexBuffer.cpp:101
void Release(VBChunk *chunk)
Return given chunk to this buffer.
Definition: VertexBuffer.cpp:164
void UploadIfNeeded(Renderer::Backend::IDeviceCommandContext *deviceCommandContext)
Definition: VertexBuffer.cpp:226
size_t m_VertexSize
Vertex size of this vertex buffer.
Definition: VertexBuffer.h:150
bool m_HasNeededChunks
Definition: VertexBuffer.h:162
std::unique_ptr< Renderer::Backend::IBuffer > m_Buffer
Definition: VertexBuffer.h:160
size_t m_MaxVertices
Number of vertices of above size in this buffer.
Definition: VertexBuffer.h:152
Renderer::Backend::IBuffer * GetBuffer()
Definition: VertexBuffer.h:135
void DumpStatus() const
Definition: VertexBuffer.cpp:300
bool CompatibleVertexType(const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const uint32_t usage) const
Returns true if this vertex buffer is compatible with the specified vertex type and intended usage.
Definition: VertexBuffer.cpp:89
size_t GetBytesAllocated() const
Definition: VertexBuffer.cpp:295
size_t GetBytesReserved() const
Definition: VertexBuffer.cpp:290
std::vector< VBChunk * > m_AllocList
List of allocated chunks.
Definition: VertexBuffer.h:156
Definition: IBuffer.h:32
Type
Definition: IBuffer.h:35
Definition: IDeviceCommandContext.h:42
Definition: IDevice.h:48
Definition: VertexBuffer.h:65
CVertexBuffer * m_Owner
Definition: VertexBuffer.h:67
bool m_Needed
Definition: VertexBuffer.h:82
void * m_BackingStore
Definition: VertexBuffer.h:73
size_t m_Count
Definition: VertexBuffer.h:71
~VBChunk()
Definition: VertexBuffer.h:89
VBChunk()
Definition: VertexBuffer.h:88
size_t m_Index
Definition: VertexBuffer.h:69
bool m_Dirty
Definition: VertexBuffer.h:78
unsigned int uint32_t
Definition: wposix_types.h:53