Blender V5.0
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
10
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 <cstring>
21
22/* -------------------------------------------------------------------- */
25
26namespace blender::gpu {
27
28size_t VertBuf::memory_usage = 0;
29
31{
32 /* Needed by some code check. */
33 format.attr_len = 0;
34}
35
37{
38 /* Should already have been cleared. */
40}
41
43{
44#if 0 /* Disabled until Grease pencil. Comply to this. */
46 BLI_assert_msg(format.attr_len == 1,
47 "Only single attribute format are supported for buffer textures");
48 }
49#endif
50 /* Strip extended usage flags. */
52#ifndef NDEBUG
53 /* Store extended usage. */
54 extended_usage_ = usage;
55#endif
57 GPU_vertformat_copy(&this->format, format);
58 if (!this->format.packed) {
59 VertexFormat_pack(&this->format);
60 }
62}
63
65{
66 this->release_data();
68}
69
70void VertBuf::allocate(uint vert_len)
71{
72 BLI_assert(format.packed);
73 /* Catch any unnecessary usage. */
74 BLI_assert(vertex_alloc != vert_len || data_ == nullptr);
75 vertex_len = vertex_alloc = vert_len;
76
77 this->acquire_data();
78
80}
81
82void VertBuf::resize(uint vert_len)
83{
84 /* Catch any unnecessary usage. */
85 BLI_assert(vertex_alloc != vert_len);
86 vertex_len = vertex_alloc = vert_len;
87
88 this->resize_data();
89
91}
92
94{
95 this->upload_data();
96}
97
98} // namespace blender::gpu
99
101
102/* -------------------------------------------------------------------- */
105
106using namespace blender;
107using namespace blender::gpu;
108
109/* -------- Creation & deletion -------- */
110
115
122
124 const GPUVertFormat &format,
125 GPUUsageType usage)
126{
127 verts.init(format, usage);
128}
129
135
142
144{
145 verts->read(data);
146}
147
149{
150 verts->clear();
151}
152
154{
155 verts->clear();
156 verts->reference_remove();
157}
158
160{
161 verts->reference_add();
162}
163
165{
166 verts->reference_remove();
167}
168
169/* -------- Data update -------- */
170
172{
173 verts.allocate(v_len);
174}
175
177{
178 verts.resize(v_len);
179}
180
182{
183 BLI_assert(verts.data<uchar>().data() != nullptr); /* Only for dynamic data. */
184 BLI_assert(v_len <= verts.vertex_alloc);
185 verts.vertex_len = v_len;
186}
187
188void GPU_vertbuf_attr_set(VertBuf *verts, uint a_idx, uint v_idx, const void *data)
189{
190 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
191 const GPUVertFormat *format = &verts->format;
192 const GPUVertAttr *a = &format->attrs[a_idx];
193 BLI_assert(v_idx < verts->vertex_alloc);
194 BLI_assert(a_idx < format->attr_len);
195 BLI_assert(verts->data<uchar>().data() != nullptr);
197 memcpy(verts->data<uchar>().data() + a->offset + v_idx * format->stride, data, a->type.size());
198}
199
200void GPU_vertbuf_attr_fill(VertBuf *verts, uint a_idx, const void *data)
201{
202 const GPUVertFormat *format = &verts->format;
203 BLI_assert(a_idx < format->attr_len);
204 const GPUVertAttr *a = &format->attrs[a_idx];
205 const uint stride = a->type.size(); /* tightly packed input data */
207 GPU_vertbuf_attr_fill_stride(verts, a_idx, stride, data);
208}
209
210void GPU_vertbuf_vert_set(VertBuf *verts, uint v_idx, const void *data)
211{
212 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
213 const GPUVertFormat *format = &verts->format;
214 BLI_assert(v_idx < verts->vertex_alloc);
215 BLI_assert(verts->data<uchar>().data() != nullptr);
217 memcpy(verts->data<uchar>().data() + v_idx * format->stride, data, format->stride);
218}
219
220void GPU_vertbuf_attr_fill_stride(VertBuf *verts, uint a_idx, uint stride, const void *data)
221{
222 BLI_assert(verts->get_usage_type() != GPU_USAGE_DEVICE_ONLY);
223 const GPUVertFormat *format = &verts->format;
224 const GPUVertAttr *a = &format->attrs[a_idx];
225 BLI_assert(a_idx < format->attr_len);
226 BLI_assert(verts->data<uchar>().data() != nullptr);
228 const uint vertex_len = verts->vertex_len;
229
230 if (format->attr_len == 1 && stride == format->stride) {
231 /* we can copy it all at once */
232 memcpy(verts->data<uchar>().data(), data, vertex_len * a->type.size());
233 }
234 else {
235 /* we must copy it per vertex */
236 for (uint v = 0; v < vertex_len; v++) {
237 memcpy(verts->data<uchar>().data() + a->offset + v * format->stride,
238 (const uchar *)data + v * stride,
239 a->type.size());
240 }
241 }
242}
243
245{
246 const GPUVertFormat *format = &verts->format;
247 const GPUVertAttr *a = &format->attrs[a_idx];
248 BLI_assert(a_idx < format->attr_len);
249 BLI_assert(verts->data<uchar>().data() != nullptr);
250
253 access->size = a->type.size();
254 access->stride = format->stride;
255 access->data = (uchar *)verts->data<uchar>().data() + a->offset;
256 access->data_init = access->data;
257#ifndef NDEBUG
258 access->_data_end = access->data_init + size_t(verts->vertex_alloc * format->stride);
259#endif
260}
261
262/* -------- Getters -------- */
263
265{
266 return &verts->format;
267}
268
270{
271 return verts->vertex_alloc;
272}
273
275{
276 return verts->vertex_len;
277}
278
280{
281 return verts->flag;
282}
283
288
293
295{
296 verts->upload();
297}
298
300{
301 verts->wrap_handle(handle);
302}
303
305{
306 verts->bind_as_ssbo(binding);
307}
308
310{
311 verts->bind_as_texture(binding);
312}
313
315{
316 verts->update_sub(start, len, data);
317}
318
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
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)
blender::gpu::VertBuf * GPU_vertbuf_create_on_device(const GPUVertFormat &format, uint v_len)
void GPU_vertbuf_init_build_on_device(blender::gpu::VertBuf &verts, const GPUVertFormat &format, uint v_len)
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
@ GPU_VERTBUF_DATA_UPLOADED
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.
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
static GPUBackend * get()
virtual VertBuf * vertbuf_alloc()=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 resize_data()=0
virtual void release_data()=0
virtual void acquire_data()=0
static float verts[][3]
void VertexFormat_pack(GPUVertFormat *format)
format
struct GPUVertAttr::Type type
unsigned char * data_init
unsigned char * data
unsigned char * _data_end
uint len