Pyrogenesis  trunk
VertexBuffer.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 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 
27 
28 #include <memory>
29 #include <vector>
30 
31 /**
32  * CVertexBuffer: encapsulation of backend buffers, also supplying
33  * some additional functionality for sharing buffers between multiple objects.
34  *
35  * The class can be used in two modes, depending on the usage parameter:
36  *
37  * Static buffer: Call Allocate() with backingStore = nullptr. Then call
38  * UpdateChunkVertices() with any pointer - the data will be immediately copied
39  * to the buffer. This should be used for vertex data that rarely changes.
40  *
41  * Dynamic buffer: Call Allocate() with backingStore pointing
42  * at some memory that will remain valid for the lifetime of the CVertexBuffer.
43  * This should be used for vertex data that may change every frame.
44  * Rendering is expected to occur in two phases:
45  * - "Prepare" phase:
46  * If this chunk is going to be used for rendering during the next rendering phase,
47  * you must call PrepareForRendering().
48  * If the vertex data in backingStore has been modified since the last uploading phase,
49  * you must call UpdateChunkVertices().
50  * - "Upload" phase:
51  * UploadedIfNeeded() can be called (multiple times). The vertex data will be uploaded
52  * to the GPU if necessary.
53  * It is okay to have multiple prepare/upload cycles per frame (though slightly less
54  * efficient), but they must occur sequentially.
55  */
57 {
59 
60 public:
61 
62  // VBChunk: describes a portion of this vertex buffer
63  struct VBChunk
64  {
65  // Owning (parent) vertex buffer
67  // Start index of this chunk in owner
68  size_t m_Index;
69  // Number of vertices used by chunk
70  size_t m_Count;
71  // If UseStreaming() is true, points at the data for this chunk
73 
74  // If true, the backend buffer is not consistent with the chunk's
75  // backing store (and will need to be re-uploaded before rendering with
76  // this chunk).
77  bool m_Dirty;
78 
79  // If true, we have been told this chunk is going to be used for
80  // rendering in the next uploading phase and will need to be uploaded
81  bool m_Needed;
82 
83  private:
84  // Only CVertexBuffer can construct/delete these
85  // (Other people should use g_VBMan.AllocateChunk)
86  friend class CVertexBuffer;
87  VBChunk() {}
88  ~VBChunk() {}
89  };
90 
91 public:
92  // constructor, destructor
94  const char* name, const size_t vertexSize,
95  const Renderer::Backend::IBuffer::Type type, const bool dynamic);
97  const char* name, const size_t vertexSize,
98  const Renderer::Backend::IBuffer::Type type, const bool dynamic,
99  const size_t maximumBufferSize);
100  ~CVertexBuffer();
101 
102  void UploadIfNeeded(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
103 
104  /// Make the vertex data available for the next usage.
105  void PrepareForRendering(VBChunk* chunk);
106 
107  /// Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer.
108  void UpdateChunkVertices(VBChunk* chunk, void* data);
109 
110  size_t GetVertexSize() const { return m_VertexSize; }
111  size_t GetBytesReserved() const;
112  size_t GetBytesAllocated() const;
113 
114  /// Returns true if this vertex buffer is compatible with the specified vertex type and intended usage.
116  const size_t vertexSize, const Renderer::Backend::IBuffer::Type type,
117  const bool dynamic) const;
118 
119  void DumpStatus() const;
120 
121  /**
122  * Given the usage flags of a buffer that has been (or will be) allocated:
123  *
124  * If true, we assume the buffer is going to be modified on every frame,
125  * so we will re-upload the entire buffer every frame using glMapBuffer.
126  * This requires the buffer's owner to hold onto its backing store.
127  *
128  * If false, we assume it will change rarely, and use direct upload to
129  * update it incrementally. The backing store can be freed to save memory.
130  */
131  static bool UseStreaming(const bool dynamic);
132 
134 
135 private:
136  friend class CVertexBufferManager; // allow allocate only via CVertexBufferManager
137 
138  /// Try to allocate a buffer of given number of vertices (each of given size),
139  /// and with the given type - return null if no free chunks available
140  VBChunk* Allocate(
141  const size_t vertexSize, const size_t numberOfVertices,
142  const Renderer::Backend::IBuffer::Type type, const bool dynamic,
143  void* backingStore);
144  /// Return given chunk to this buffer
145  void Release(VBChunk* chunk);
146 
147  /// Vertex size of this vertex buffer
148  size_t m_VertexSize;
149  /// Number of vertices of above size in this buffer
151  /// List of free chunks in this buffer
152  std::vector<VBChunk*> m_FreeList;
153  /// List of allocated chunks
154  std::vector<VBChunk*> m_AllocList;
155  /// Available free vertices - total of all free vertices in the free list
157 
158  std::unique_ptr<Renderer::Backend::IBuffer> m_Buffer;
159 
161 };
162 
163 #endif // INCLUDED_VERTEXBUFFER
size_t m_Index
Definition: VertexBuffer.h:68
Definition: IBuffer.h:31
std::vector< VBChunk * > m_FreeList
List of free chunks in this buffer.
Definition: VertexBuffer.h:152
void PrepareForRendering(VBChunk *chunk)
Make the vertex data available for the next usage.
Definition: VertexBuffer.cpp:320
bool m_Needed
Definition: VertexBuffer.h:81
friend class CVertexBuffer
Definition: VertexBuffer.h:86
Type
Definition: IBuffer.h:34
VBChunk()
Definition: VertexBuffer.h:87
Definition: VertexBufferManager.h:34
VBChunk * Allocate(const size_t vertexSize, const size_t numberOfVertices, const Renderer::Backend::IBuffer::Type type, const bool dynamic, void *backingStore)
Try to allocate a buffer of given number of vertices (each of given size), and with the given type - ...
Definition: VertexBuffer.cpp:103
size_t GetBytesAllocated() const
Definition: VertexBuffer.cpp:297
bool CompatibleVertexType(const size_t vertexSize, const Renderer::Backend::IBuffer::Type type, const bool dynamic) const
Returns true if this vertex buffer is compatible with the specified vertex type and intended usage...
Definition: VertexBuffer.cpp:91
Definition: VertexBuffer.h:63
static bool UseStreaming(const bool dynamic)
Given the usage flags of a buffer that has been (or will be) allocated:
Definition: VertexBuffer.cpp:315
CVertexBuffer: encapsulation of backend buffers, also supplying some additional functionality for sha...
Definition: VertexBuffer.h:56
size_t GetVertexSize() const
Definition: VertexBuffer.h:110
void UploadIfNeeded(Renderer::Backend::IDeviceCommandContext *deviceCommandContext)
Definition: VertexBuffer.cpp:228
std::vector< VBChunk * > m_AllocList
List of allocated chunks.
Definition: VertexBuffer.h:154
size_t m_FreeVertices
Available free vertices - total of all free vertices in the free list.
Definition: VertexBuffer.h:156
NONCOPYABLE(CVertexBuffer)
size_t GetBytesReserved() const
Definition: VertexBuffer.cpp:292
~VBChunk()
Definition: VertexBuffer.h:88
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:208
void Release(VBChunk *chunk)
Return given chunk to this buffer.
Definition: VertexBuffer.cpp:166
std::unique_ptr< Renderer::Backend::IBuffer > m_Buffer
Definition: VertexBuffer.h:158
size_t m_Count
Definition: VertexBuffer.h:70
size_t m_MaxVertices
Number of vertices of above size in this buffer.
Definition: VertexBuffer.h:150
Renderer::Backend::IBuffer * GetBuffer()
Definition: VertexBuffer.h:133
CVertexBuffer * m_Owner
Definition: VertexBuffer.h:66
size_t m_VertexSize
Vertex size of this vertex buffer.
Definition: VertexBuffer.h:148
void DumpStatus() const
Definition: VertexBuffer.cpp:302
void * m_BackingStore
Definition: VertexBuffer.h:72
bool m_Dirty
Definition: VertexBuffer.h:77
Definition: IDeviceCommandContext.h:40
bool m_HasNeededChunks
Definition: VertexBuffer.h:160
~CVertexBuffer()
Definition: VertexBuffer.cpp:80