Blender V4.3
gpu_vertex_buffer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "MEM_guardedalloc.h"
12
13#include "gpu_backend.hh"
15
16#include "GPU_vertex_buffer.hh"
17
18#include "gpu_context_private.hh" /* TODO: remove. */
19
20#include "GPU_vertex_buffer.hh"
21
22#include <cstring>
23
24/* -------------------------------------------------------------------- */
28namespace blender::gpu {
29
30size_t VertBuf::memory_usage = 0;
31
33{
34 /* Needed by some code check. */
35 format.attr_len = 0;
36}
37
39{
40 /* Should already have been cleared. */
42}
43
45{
46 /* Strip extended usage flags. */
47 usage_ = usage & ~GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
48#ifndef NDEBUG
49 /* Store extended usage. */
50 extended_usage_ = usage;
51#endif
53 GPU_vertformat_copy(&this->format, format);
54 /* Avoid packing vertex formats which are used for texture buffers.
55 * These cases use singular types and do not need packing. They must
56 * also not have increased alignment padding to the minimum per-vertex stride. */
59 }
60 if (!this->format.packed) {
61 VertexFormat_pack(&this->format);
62 }
64}
65
67{
68 this->release_data();
70}
71
73{
75 /* Full copy. */
76 *dst = *this;
77 /* Almost full copy... */
78 dst->handle_refcount_ = 1;
79 /* Metadata. */
80#ifndef NDEBUG
82#endif
83 /* Duplicate all needed implementation specifics data. */
84 this->duplicate_data(dst);
85 return dst;
86}
87
88void VertBuf::allocate(uint vert_len)
89{
90 BLI_assert(format.packed);
91 /* Catch any unnecessary usage. */
92 BLI_assert(vertex_alloc != vert_len || data_ == nullptr);
93 vertex_len = vertex_alloc = vert_len;
94
95 this->acquire_data();
96
98}
99
100void VertBuf::resize(uint vert_len)
101{
102 /* Catch any unnecessary usage. */
103 BLI_assert(vertex_alloc != vert_len);
104 vertex_len = vertex_alloc = vert_len;
105
106 this->resize_data();
107
109}
110
112{
113 this->upload_data();
114}
115
116} // namespace blender::gpu
117
120/* -------------------------------------------------------------------- */
124using namespace blender;
125using namespace blender::gpu;
126
127/* -------- Creation & deletion -------- */
128
133
140
142 const GPUVertFormat &format,
143 GPUUsageType usage)
144{
145 verts.init(format, usage);
146}
147
153
158
159void GPU_vertbuf_read(const VertBuf *verts, void *data)
160{
161 verts->read(data);
162}
163
165{
166 verts->clear();
167}
168
170{
171 verts->clear();
172 verts->reference_remove();
173}
174
176{
177 verts->reference_add();
178}
179
181{
182 verts->reference_remove();
183}
184
185/* -------- Data update -------- */
186
188{
189 verts.allocate(v_len);
190}
191
193{
194 verts.resize(v_len);
195}
196
198{
199 BLI_assert(verts.data<uchar>().data() != nullptr); /* Only for dynamic data. */
200 BLI_assert(v_len <= verts.vertex_alloc);
201 verts.vertex_len = v_len;
202}
203
204void GPU_vertbuf_attr_set(VertBuf *verts, uint a_idx, uint v_idx, const void *data)
205{
206 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
207 const GPUVertFormat *format = &verts->format;
208 const GPUVertAttr *a = &format->attrs[a_idx];
209 BLI_assert(v_idx < verts->vertex_alloc);
210 BLI_assert(a_idx < format->attr_len);
211 BLI_assert(verts->data<uchar>().data() != nullptr);
213 memcpy(verts->data<uchar>().data() + a->offset + v_idx * format->stride, data, a->size);
214}
215
216void GPU_vertbuf_attr_fill(VertBuf *verts, uint a_idx, const void *data)
217{
218 const GPUVertFormat *format = &verts->format;
219 BLI_assert(a_idx < format->attr_len);
220 const GPUVertAttr *a = &format->attrs[a_idx];
221 const uint stride = a->size; /* tightly packed input data */
223 GPU_vertbuf_attr_fill_stride(verts, a_idx, stride, data);
224}
225
226void GPU_vertbuf_vert_set(VertBuf *verts, uint v_idx, const void *data)
227{
228 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
229 const GPUVertFormat *format = &verts->format;
230 BLI_assert(v_idx < verts->vertex_alloc);
231 BLI_assert(verts->data<uchar>().data() != nullptr);
233 memcpy(verts->data<uchar>().data() + v_idx * format->stride, data, format->stride);
234}
235
236void GPU_vertbuf_attr_fill_stride(VertBuf *verts, uint a_idx, uint stride, const void *data)
237{
238 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
239 const GPUVertFormat *format = &verts->format;
240 const GPUVertAttr *a = &format->attrs[a_idx];
241 BLI_assert(a_idx < format->attr_len);
242 BLI_assert(verts->data<uchar>().data() != nullptr);
244 const uint vertex_len = verts->vertex_len;
245
246 if (format->attr_len == 1 && stride == format->stride) {
247 /* we can copy it all at once */
248 memcpy(verts->data<uchar>().data(), data, vertex_len * a->size);
249 }
250 else {
251 /* we must copy it per vertex */
252 for (uint v = 0; v < vertex_len; v++) {
253 memcpy(verts->data<uchar>().data() + a->offset + v * format->stride,
254 (const uchar *)data + v * stride,
255 a->size);
256 }
257 }
258}
259
261{
262 const GPUVertFormat *format = &verts->format;
263 const GPUVertAttr *a = &format->attrs[a_idx];
264 BLI_assert(a_idx < format->attr_len);
265 BLI_assert(verts->data<uchar>().data() != nullptr);
266
268 verts->flag &= ~GPU_VERTBUF_DATA_UPLOADED;
269 access->size = a->size;
270 access->stride = format->stride;
271 access->data = (uchar *)verts->data<uchar>().data() + a->offset;
272 access->data_init = access->data;
273#ifndef NDEBUG
274 access->_data_end = access->data_init + size_t(verts->vertex_alloc * format->stride);
275#endif
276}
277
278/* -------- Getters -------- */
279
281{
282 return &verts->format;
283}
284
286{
287 return verts->vertex_alloc;
288}
289
291{
292 return verts->vertex_len;
293}
294
296{
297 return verts->flag;
298}
299
304
309
311{
312 verts->upload();
313}
314
316{
317 verts->wrap_handle(handle);
318}
319
321{
322 verts->bind_as_ssbo(binding);
323}
324
326{
327 verts->bind_as_texture(binding);
328}
329
330void GPU_vertbuf_update_sub(VertBuf *verts, uint start, uint len, const void *data)
331{
332 verts->update_sub(start, len, data);
333}
334
#define BLI_assert(a)
Definition BLI_assert.h:50
unsigned char uchar
unsigned int uint
void GPU_vertbuf_attr_get_raw_data(blender::gpu::VertBuf *, uint a_idx, GPUVertBufRaw *access)
void GPU_vertbuf_attr_fill_stride(blender::gpu::VertBuf *, uint a_idx, uint stride, const void *data)
void GPU_vertbuf_init_build_on_device(blender::gpu::VertBuf &verts, const GPUVertFormat &format, uint v_len)
blender::gpu::VertBuf * GPU_vertbuf_duplicate(blender::gpu::VertBuf *verts)
void GPU_vertbuf_vert_set(blender::gpu::VertBuf *verts, uint v_idx, const void *data)
void GPU_vertbuf_handle_ref_remove(blender::gpu::VertBuf *verts)
void GPU_vertbuf_use(blender::gpu::VertBuf *)
void GPU_vertbuf_data_resize(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_attr_fill(blender::gpu::VertBuf *, uint a_idx, const void *data)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
void GPU_vertbuf_handle_ref_add(blender::gpu::VertBuf *verts)
void GPU_vertbuf_data_len_set(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
GPUVertBufStatus
@ GPU_VERTBUF_INIT
@ GPU_VERTBUF_INVALID
@ GPU_VERTBUF_DATA_DIRTY
void GPU_vertbuf_wrap_handle(blender::gpu::VertBuf *verts, uint64_t handle)
void GPU_vertbuf_read(const blender::gpu::VertBuf *verts, void *data)
uint GPU_vertbuf_get_memory_usage()
GPUVertBufStatus GPU_vertbuf_get_status(const blender::gpu::VertBuf *verts)
blender::gpu::VertBuf * GPU_vertbuf_calloc()
void GPU_vertbuf_clear(blender::gpu::VertBuf *verts)
const GPUVertFormat * GPU_vertbuf_get_format(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_bind_as_ssbo(blender::gpu::VertBuf *verts, int binding)
void GPU_vertbuf_update_sub(blender::gpu::VertBuf *verts, uint start, uint len, const void *data)
void GPU_vertbuf_init_with_format_ex(blender::gpu::VertBuf &verts, const GPUVertFormat &format, GPUUsageType)
void GPU_vertbuf_bind_as_texture(blender::gpu::VertBuf *verts, int binding)
uint GPU_vertbuf_get_vertex_len(const blender::gpu::VertBuf *verts)
void GPU_vertbuf_discard(blender::gpu::VertBuf *)
@ GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY
@ GPU_USAGE_DEVICE_ONLY
uint GPU_vertbuf_get_vertex_alloc(const blender::gpu::VertBuf *verts)
void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat &src)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static GPUBackend * get()
virtual VertBuf * vertbuf_alloc()=0
virtual void read(void *data) const =0
void init(const GPUVertFormat &format, GPUUsageType usage)
void resize(uint vert_len)
virtual void upload_data()=0
void allocate(uint vert_len)
virtual void duplicate_data(VertBuf *dst)=0
virtual void resize_data()=0
virtual void release_data()=0
virtual void acquire_data()=0
int len
static float verts[][3]
void VertexFormat_texture_buffer_pack(GPUVertFormat *format)
void VertexFormat_pack(GPUVertFormat *format)
format
unsigned __int64 uint64_t
Definition stdint.h:90
unsigned char * data_init
unsigned char * data
unsigned char * _data_end