Blender  V3.3
gpu_vertex_buffer.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 by Mike Erwin. All rights reserved. */
3 
10 #include "MEM_guardedalloc.h"
11 
12 #include "gpu_backend.hh"
14 
15 #include "gpu_context_private.hh" /* TODO: remove. */
16 
18 
19 #include <cstring>
20 
21 /* -------------------------------------------------------------------- */
25 namespace blender::gpu {
26 
27 size_t VertBuf::memory_usage = 0;
28 
30 {
31  /* Needed by some code check. */
32  format.attr_len = 0;
33 }
34 
36 {
37  /* Should already have been cleared. */
39 }
40 
42 {
43  usage_ = usage;
45  GPU_vertformat_copy(&this->format, format);
46  if (!format->packed) {
47  VertexFormat_pack(&this->format);
48  }
50 }
51 
53 {
54  this->release_data();
56 }
57 
59 {
61  /* Full copy. */
62  *dst = *this;
63  /* Almost full copy... */
64  dst->handle_refcount_ = 1;
65  /* Duplicate all needed implementation specifics data. */
66  this->duplicate_data(dst);
67  return dst;
68 }
69 
70 void 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 
82 void 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 
102 /* -------------------------------------------------------------------- */
106 using namespace blender;
107 using namespace blender::gpu;
108 
109 /* -------- Creation & deletion -------- */
110 
112 {
113  return wrap(GPUBackend::get()->vertbuf_alloc());
114 }
115 
117 {
119  unwrap(verts)->init(format, usage);
120  return verts;
121 }
122 
124  const GPUVertFormat *format,
125  GPUUsageType usage)
126 {
127  unwrap(verts_)->init(format, usage);
128 }
129 
131 {
134 }
135 
137 {
138  return wrap(unwrap(verts_)->duplicate());
139 }
140 
142 {
143  return unwrap(verts)->read();
144 }
145 
146 void *GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data)
147 {
148  return unwrap(verts)->unmap(mapped_data);
149 }
150 
152 {
153  unwrap(verts)->clear();
154 }
155 
157 {
158  unwrap(verts)->clear();
159  unwrap(verts)->reference_remove();
160 }
161 
163 {
164  unwrap(verts)->reference_add();
165 }
166 
168 {
169  unwrap(verts)->reference_remove();
170 }
171 
172 /* -------- Data update -------- */
173 
175 {
176  unwrap(verts)->allocate(v_len);
177 }
178 
180 {
181  unwrap(verts)->resize(v_len);
182 }
183 
185 {
186  VertBuf *verts = unwrap(verts_);
187  BLI_assert(verts->data != nullptr); /* Only for dynamic data. */
188  BLI_assert(v_len <= verts->vertex_alloc);
189  verts->vertex_len = v_len;
190 }
191 
192 void GPU_vertbuf_attr_set(GPUVertBuf *verts_, uint a_idx, uint v_idx, const void *data)
193 {
194  VertBuf *verts = unwrap(verts_);
195  const GPUVertFormat *format = &verts->format;
196  const GPUVertAttr *a = &format->attrs[a_idx];
197  BLI_assert(v_idx < verts->vertex_alloc);
198  BLI_assert(a_idx < format->attr_len);
199  BLI_assert(verts->data != nullptr);
200  verts->flag |= GPU_VERTBUF_DATA_DIRTY;
201  memcpy(verts->data + a->offset + v_idx * format->stride, data, a->size);
202 }
203 
204 void GPU_vertbuf_attr_fill(GPUVertBuf *verts_, uint a_idx, const void *data)
205 {
206  VertBuf *verts = unwrap(verts_);
207  const GPUVertFormat *format = &verts->format;
208  BLI_assert(a_idx < format->attr_len);
209  const GPUVertAttr *a = &format->attrs[a_idx];
210  const uint stride = a->size; /* tightly packed input data */
211  verts->flag |= GPU_VERTBUF_DATA_DIRTY;
212  GPU_vertbuf_attr_fill_stride(verts_, a_idx, stride, data);
213 }
214 
215 void GPU_vertbuf_vert_set(GPUVertBuf *verts_, uint v_idx, const void *data)
216 {
217  VertBuf *verts = unwrap(verts_);
218  const GPUVertFormat *format = &verts->format;
219  BLI_assert(v_idx < verts->vertex_alloc);
220  BLI_assert(verts->data != nullptr);
221  verts->flag |= GPU_VERTBUF_DATA_DIRTY;
222  memcpy(verts->data + v_idx * format->stride, data, format->stride);
223 }
224 
225 void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts_, uint a_idx, uint stride, const void *data)
226 {
227  VertBuf *verts = unwrap(verts_);
228  const GPUVertFormat *format = &verts->format;
229  const GPUVertAttr *a = &format->attrs[a_idx];
230  BLI_assert(a_idx < format->attr_len);
231  BLI_assert(verts->data != nullptr);
232  verts->flag |= GPU_VERTBUF_DATA_DIRTY;
233  const uint vertex_len = verts->vertex_len;
234 
235  if (format->attr_len == 1 && stride == format->stride) {
236  /* we can copy it all at once */
237  memcpy(verts->data, data, vertex_len * a->size);
238  }
239  else {
240  /* we must copy it per vertex */
241  for (uint v = 0; v < vertex_len; v++) {
242  memcpy(
243  verts->data + a->offset + v * format->stride, (const uchar *)data + v * stride, a->size);
244  }
245  }
246 }
247 
249 {
250  VertBuf *verts = unwrap(verts_);
251  const GPUVertFormat *format = &verts->format;
252  const GPUVertAttr *a = &format->attrs[a_idx];
253  BLI_assert(a_idx < format->attr_len);
254  BLI_assert(verts->data != nullptr);
255 
256  verts->flag |= GPU_VERTBUF_DATA_DIRTY;
258  access->size = a->size;
259  access->stride = format->stride;
260  access->data = (uchar *)verts->data + a->offset;
261  access->data_init = access->data;
262 #ifdef DEBUG
263  access->_data_end = access->data_init + (size_t)(verts->vertex_alloc * format->stride);
264 #endif
265 }
266 
267 /* -------- Getters -------- */
268 
270 {
271  /* TODO: Assert that the format has no padding. */
272  return unwrap(verts)->data;
273 }
274 
276 {
277  VertBuf *verts = unwrap(verts_);
278  /* TODO: Assert that the format has no padding. */
279  BLI_assert(verts->data);
280  void *data = verts->data;
281  verts->data = nullptr;
282  return data;
283 }
284 
286 {
287  return &unwrap(verts)->format;
288 }
289 
291 {
292  return unwrap(verts)->vertex_alloc;
293 }
294 
296 {
297  return unwrap(verts)->vertex_len;
298 }
299 
301 {
302  return unwrap(verts)->flag;
303 }
304 
306 {
308 }
309 
311 {
312  return VertBuf::memory_usage;
313 }
314 
316 {
317  unwrap(verts)->upload();
318 }
319 
321 {
322  unwrap(verts)->wrap_handle(handle);
323 }
324 
325 void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding)
326 {
327  unwrap(verts)->bind_as_ssbo(binding);
328 }
329 
330 void GPU_vertbuf_bind_as_texture(struct GPUVertBuf *verts, int binding)
331 {
332  unwrap(verts)->bind_as_texture(binding);
333 }
334 
336 {
337  unwrap(verts)->update_sub(start, len, data);
338 }
339 
#define BLI_assert(a)
Definition: BLI_assert.h:46
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
struct GPUVertBuf GPUVertBuf
GPUVertBufStatus
@ GPU_VERTBUF_INIT
@ GPU_VERTBUF_INVALID
@ GPU_VERTBUF_DATA_DIRTY
@ GPU_VERTBUF_DATA_UPLOADED
GPUUsageType
@ GPU_USAGE_DEVICE_ONLY
void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static GPUBackend * get()
Definition: gpu_context.cc:292
virtual VertBuf * vertbuf_alloc()=0
void resize(uint vert_len)
virtual void upload_data()=0
void init(const GPUVertFormat *format, GPUUsageType usage)
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
static void * vertbuf_alloc(const OpenSubdiv_Buffer *interface, const uint len)
int len
Definition: draw_manager.c:108
static float verts[][3]
void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len)
void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len)
void * GPU_vertbuf_steal_data(GPUVertBuf *verts_)
uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts)
void GPU_vertbuf_wrap_handle(GPUVertBuf *verts, uint64_t handle)
void * GPU_vertbuf_unmap(const GPUVertBuf *verts, const void *mapped_data)
const GPUVertFormat * GPU_vertbuf_get_format(const GPUVertBuf *verts)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *verts_, uint a_idx, GPUVertBufRaw *access)
uint GPU_vertbuf_get_vertex_len(const GPUVertBuf *verts)
void GPU_vertbuf_data_len_set(GPUVertBuf *verts_, uint v_len)
void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, const void *data)
GPUVertBuf * GPU_vertbuf_duplicate(GPUVertBuf *verts_)
void GPU_vertbuf_clear(GPUVertBuf *verts)
void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts)
void GPU_vertbuf_init_with_format_ex(GPUVertBuf *verts_, const GPUVertFormat *format, GPUUsageType usage)
void GPU_vertbuf_attr_fill(GPUVertBuf *verts_, uint a_idx, const void *data)
void GPU_vertbuf_attr_set(GPUVertBuf *verts_, uint a_idx, uint v_idx, const void *data)
void GPU_vertbuf_bind_as_ssbo(struct GPUVertBuf *verts, int binding)
GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts)
void * GPU_vertbuf_get_data(const GPUVertBuf *verts)
uint GPU_vertbuf_get_memory_usage()
void GPU_vertbuf_attr_fill_stride(GPUVertBuf *verts_, uint a_idx, uint stride, const void *data)
GPUVertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat *format, GPUUsageType usage)
void GPU_vertbuf_use(GPUVertBuf *verts)
void GPU_vertbuf_init_build_on_device(GPUVertBuf *verts, GPUVertFormat *format, uint v_len)
const void * GPU_vertbuf_read(GPUVertBuf *verts)
void GPU_vertbuf_discard(GPUVertBuf *verts)
void GPU_vertbuf_vert_set(GPUVertBuf *verts_, uint v_idx, const void *data)
void GPU_vertbuf_bind_as_texture(struct GPUVertBuf *verts, int binding)
void GPU_vertbuf_handle_ref_add(GPUVertBuf *verts)
GPUVertBuf * GPU_vertbuf_calloc()
void GPU_vertbuf_tag_dirty(GPUVertBuf *verts)
void VertexFormat_pack(GPUVertFormat *format)
format
Definition: logImageCore.h:38
static unsigned a[3]
Definition: RandGen.cpp:78
static GPUContext * wrap(Context *ctx)
static Context * unwrap(GPUContext *ctx)
unsigned __int64 uint64_t
Definition: stdint.h:90
unsigned char * data_init
unsigned char * data