Blender  V3.3
draw_instance_data.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
17 #include "draw_instance_data.h"
18 #include "draw_manager.h"
19 
20 #include "DRW_engine.h"
21 #include "DRW_render.h" /* For DRW_shgroup_get_instance_count() */
22 
23 #include "GPU_material.h"
24 
25 #include "DNA_particle_types.h"
26 
27 #include "BKE_duplilist.h"
28 
29 #include "RNA_access.h"
30 #include "RNA_path.h"
31 
32 #include "BLI_bitmap.h"
33 #include "BLI_memblock.h"
34 #include "BLI_mempool.h"
35 #include "BLI_utildefines.h"
36 #include "MEM_guardedalloc.h"
37 
40  bool used; /* If this data is used or not. */
41  size_t data_size; /* Size of one instance data. */
43 };
44 
47  /* Linked lists for all possible data pool size */
50 
54 };
55 
56 typedef struct DRWTempBufferHandle {
61  int *vert_len;
63 
64 typedef struct DRWTempInstancingHandle {
74 
76 
78 {
79  for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN && batch->verts[i]; i++) {
81  }
82  for (int i = 0; i < GPU_BATCH_INST_VBO_MAX_LEN && batch->inst[i]; i++) {
84  }
85 }
86 
88 {
89  for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN && batch->verts[i]; i++) {
91  }
92  for (int i = 0; i < GPU_BATCH_INST_VBO_MAX_LEN && batch->inst[i]; i++) {
94  }
95 }
96 
97 /* -------------------------------------------------------------------- */
103  int *vert_len)
104 {
105  BLI_assert(format != NULL);
106  BLI_assert(vert_len != NULL);
107 
109 
110  if (handle->format != format) {
111  handle->format = format;
112  GPU_VERTBUF_DISCARD_SAFE(handle->buf);
113 
114  GPUVertBuf *vert = GPU_vertbuf_calloc();
117 
118  handle->buf = vert;
119  }
120  handle->vert_len = vert_len;
121  return handle->buf;
122 }
123 
125  GPUVertBuf *buf,
126  GPUBatch *instancer,
127  GPUBatch *geom)
128 {
129  /* Do not call this with a batch that is already an instancing batch. */
130  BLI_assert(geom->inst[0] == NULL);
131  /* Only call with one of them. */
132  BLI_assert((instancer != NULL) != (buf != NULL));
133 
135  if (handle->batch == NULL) {
136  handle->batch = GPU_batch_calloc();
137  }
138 
139  GPUBatch *batch = handle->batch;
140  bool instancer_compat = buf ? ((batch->inst[0] == buf) &&
142  ((batch->inst[0] == instancer->verts[0]) &&
143  (batch->inst[1] == instancer->verts[1]));
144  bool is_compatible = (batch->prim_type == geom->prim_type) && instancer_compat &&
145  (batch->flag & GPU_BATCH_BUILDING) == 0 && (batch->elem == geom->elem);
146  for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN && is_compatible; i++) {
147  if (batch->verts[i] != geom->verts[i]) {
148  is_compatible = false;
149  }
150  }
151 
152  if (!is_compatible) {
155  /* Save args and init later. */
156  batch->flag = GPU_BATCH_BUILDING;
157  handle->buf = buf;
158  handle->instancer = instancer;
159  handle->geom = geom;
160  }
161  return batch;
162 }
163 
165  GPUVertBuf *buf,
166  GPUPrimType prim_type)
167 {
168  GPUBatch **batch_ptr = BLI_memblock_alloc(idatalist->pool_batching);
169  if (*batch_ptr == NULL) {
170  *batch_ptr = GPU_batch_calloc();
171  }
172 
173  GPUBatch *batch = *batch_ptr;
174  bool is_compatible = (batch->verts[0] == buf) && (batch->prim_type == prim_type) &&
176  if (!is_compatible) {
178  GPU_batch_init(batch, prim_type, buf, NULL);
179  }
180  return batch;
181 }
182 
184 {
185  handle->format = NULL;
186  GPU_VERTBUF_DISCARD_SAFE(handle->buf);
187 }
188 
190 {
192  GPU_BATCH_DISCARD_SAFE(handle->batch);
193 }
194 
196 {
198 }
199 
201 {
202  /* Resize down buffers in use and send data to GPU. */
203  BLI_memblock_iter iter;
204  DRWTempBufferHandle *handle;
205  BLI_memblock_iternew(idatalist->pool_buffers, &iter);
206  while ((handle = BLI_memblock_iterstep(&iter))) {
207  if (handle->vert_len != NULL) {
208  uint vert_len = *(handle->vert_len);
209  uint target_buf_size = ((vert_len / DRW_BUFFER_VERTS_CHUNK) + 1) * DRW_BUFFER_VERTS_CHUNK;
210  if (target_buf_size < GPU_vertbuf_get_vertex_alloc(handle->buf)) {
211  GPU_vertbuf_data_resize(handle->buf, target_buf_size);
212  }
213  GPU_vertbuf_data_len_set(handle->buf, vert_len);
214  GPU_vertbuf_use(handle->buf); /* Send data. */
215  }
216  }
217  /* Finish pending instancing batches. */
218  DRWTempInstancingHandle *handle_inst;
219  BLI_memblock_iternew(idatalist->pool_instancing, &iter);
220  while ((handle_inst = BLI_memblock_iterstep(&iter))) {
221  GPUBatch *batch = handle_inst->batch;
222  if (batch && batch->flag == GPU_BATCH_BUILDING) {
223  GPUVertBuf *inst_buf = handle_inst->buf;
224  GPUBatch *inst_batch = handle_inst->instancer;
225  GPUBatch *geom = handle_inst->geom;
226  GPU_batch_copy(batch, geom);
227  if (inst_batch != NULL) {
228  for (int i = 0; i < GPU_BATCH_INST_VBO_MAX_LEN && inst_batch->verts[i]; i++) {
229  GPU_batch_instbuf_add_ex(batch, inst_batch->verts[i], false);
230  }
231  }
232  else {
233  GPU_batch_instbuf_add_ex(batch, inst_buf, false);
234  }
235  /* Add reference to avoid comparing pointers (in DRW_temp_batch_request) that could
236  * potentially be the same. This will delay the freeing of the GPUVertBuf itself. */
238  }
239  }
240  /* Resize pools and free unused. */
244 }
245 
248 /* -------------------------------------------------------------------- */
253 {
254  DRWInstanceData *idata = MEM_callocN(sizeof(DRWInstanceData), "DRWInstanceData");
255  idata->next = NULL;
256  idata->used = true;
257  idata->data_size = attr_size;
258  idata->mempool = BLI_mempool_create(sizeof(float) * idata->data_size, 0, 16, 0);
259 
260  BLI_assert(attr_size > 0);
261 
262  /* Push to linked list. */
263  if (idatalist->idata_head[attr_size - 1] == NULL) {
264  idatalist->idata_head[attr_size - 1] = idata;
265  }
266  else {
267  idatalist->idata_tail[attr_size - 1]->next = idata;
268  }
269  idatalist->idata_tail[attr_size - 1] = idata;
270 
271  return idata;
272 }
273 
275 {
277 }
278 
280 {
281  return BLI_mempool_alloc(idata->mempool);
282 }
283 
285 {
287 
288  DRWInstanceData *idata = idatalist->idata_head[attr_size - 1];
289 
290  /* Search for an unused data chunk. */
291  for (; idata; idata = idata->next) {
292  if (idata->used == false) {
293  idata->used = true;
294  return idata;
295  }
296  }
297 
298  return drw_instance_data_create(idatalist, attr_size);
299 }
300 
303 /* -------------------------------------------------------------------- */
308 {
309  DRWInstanceDataList *idatalist = MEM_callocN(sizeof(DRWInstanceDataList), "DRWInstanceDataList");
310 
311  idatalist->pool_batching = BLI_memblock_create(sizeof(GPUBatch *));
314 
315  BLI_addtail(&g_idatalists, idatalist);
316 
317  return idatalist;
318 }
319 
321 {
322  DRWInstanceData *idata, *next_idata;
323 
324  for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; i++) {
325  for (idata = idatalist->idata_head[i]; idata; idata = next_idata) {
326  next_idata = idata->next;
327  DRW_instance_data_free(idata);
328  MEM_freeN(idata);
329  }
330  idatalist->idata_head[i] = NULL;
331  idatalist->idata_tail[i] = NULL;
332  }
333 
337 
338  BLI_remlink(&g_idatalists, idatalist);
339 
340  MEM_freeN(idatalist);
341 }
342 
344 {
345  DRWInstanceData *idata;
346 
347  for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; i++) {
348  for (idata = idatalist->idata_head[i]; idata; idata = idata->next) {
349  idata->used = false;
350  }
351  }
352 }
353 
355 {
356  DRWInstanceData *idata, *next_idata;
357 
358  /* Remove unused data blocks and sanitize each list. */
359  for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; i++) {
360  idatalist->idata_tail[i] = NULL;
361  for (idata = idatalist->idata_head[i]; idata; idata = next_idata) {
362  next_idata = idata->next;
363  if (idata->used == false) {
364  if (idatalist->idata_head[i] == idata) {
365  idatalist->idata_head[i] = next_idata;
366  }
367  else {
368  /* idatalist->idata_tail[i] is guaranteed not to be null in this case. */
369  idatalist->idata_tail[i]->next = next_idata;
370  }
371  DRW_instance_data_free(idata);
372  MEM_freeN(idata);
373  }
374  else {
375  if (idatalist->idata_tail[i] != NULL) {
376  idatalist->idata_tail[i]->next = idata;
377  }
378  idatalist->idata_tail[i] = idata;
379  }
380  }
381  }
382 }
383 
385 {
386  DRWInstanceData *idata;
387 
388  for (int i = 0; i < MAX_INSTANCE_DATA_SIZE; i++) {
389  for (idata = idatalist->idata_head[i]; idata; idata = idata->next) {
391  }
392  }
393 }
394 
397 /* -------------------------------------------------------------------- */
401 #define CHUNK_LIST_STEP (1 << 4)
402 
404 typedef struct DRWSparseUniformBuf {
405  /* Memory buffers used to stage chunk data before transfer to UBOs. */
407  /* Uniform buffer objects with flushed data. */
409  /* True if the relevant chunk contains data (distinct from simply being allocated). */
411 
415 
417  unsigned int item_size,
418  unsigned int chunk_size)
419 {
420  buffer->chunk_buffers = NULL;
421  buffer->chunk_used = NULL;
422  buffer->chunk_ubos = NULL;
423  buffer->num_chunks = 0;
424  buffer->item_size = item_size;
425  buffer->chunk_size = chunk_size;
426  buffer->chunk_bytes = item_size * chunk_size;
427 }
428 
429 DRWSparseUniformBuf *DRW_sparse_uniform_buffer_new(unsigned int item_size, unsigned int chunk_size)
430 {
431  DRWSparseUniformBuf *buf = MEM_mallocN(sizeof(DRWSparseUniformBuf), __func__);
433  return buf;
434 }
435 
437 {
438  for (int i = 0; i < buffer->num_chunks; i++) {
439  if (BLI_BITMAP_TEST(buffer->chunk_used, i)) {
440  if (buffer->chunk_ubos[i] == NULL) {
441  buffer->chunk_ubos[i] = GPU_uniformbuf_create(buffer->chunk_bytes);
442  }
443  GPU_uniformbuf_update(buffer->chunk_ubos[i], buffer->chunk_buffers[i]);
444  }
445  }
446 }
447 
449 {
450  int max_used_chunk = 0;
451 
452  for (int i = 0; i < buffer->num_chunks; i++) {
453  /* Delete buffers that were not used since the last clear call. */
454  if (free_all || !BLI_BITMAP_TEST(buffer->chunk_used, i)) {
455  MEM_SAFE_FREE(buffer->chunk_buffers[i]);
456 
457  if (buffer->chunk_ubos[i]) {
458  GPU_uniformbuf_free(buffer->chunk_ubos[i]);
459  buffer->chunk_ubos[i] = NULL;
460  }
461  }
462  else {
463  max_used_chunk = i + 1;
464  }
465  }
466 
467  /* Shrink the chunk array if appropriate. */
468  const int old_num_chunks = buffer->num_chunks;
469 
470  buffer->num_chunks = (max_used_chunk + CHUNK_LIST_STEP - 1) & ~(CHUNK_LIST_STEP - 1);
471 
472  if (buffer->num_chunks == 0) {
473  /* Ensure that an empty pool holds no memory allocations. */
474  MEM_SAFE_FREE(buffer->chunk_buffers);
475  MEM_SAFE_FREE(buffer->chunk_used);
476  MEM_SAFE_FREE(buffer->chunk_ubos);
477  return;
478  }
479 
480  if (buffer->num_chunks != old_num_chunks) {
481  buffer->chunk_buffers = MEM_recallocN(buffer->chunk_buffers,
482  buffer->num_chunks * sizeof(void *));
483  buffer->chunk_ubos = MEM_recallocN(buffer->chunk_ubos, buffer->num_chunks * sizeof(void *));
484  BLI_BITMAP_RESIZE(buffer->chunk_used, buffer->num_chunks);
485  }
486 
487  BLI_bitmap_set_all(buffer->chunk_used, false, buffer->num_chunks);
488 }
489 
491 {
493  MEM_freeN(buffer);
494 }
495 
497 {
498  return buffer->num_chunks == 0;
499 }
500 
502 {
503  if (buffer && chunk < buffer->num_chunks && BLI_BITMAP_TEST(buffer->chunk_used, chunk)) {
504  return buffer->chunk_ubos[chunk];
505  }
506  return NULL;
507 }
508 
510 {
512  if (ubo) {
513  GPU_uniformbuf_bind(ubo, location);
514  }
515 }
516 
518 {
520  if (ubo) {
522  }
523 }
524 
526 {
527  if (chunk >= buffer->num_chunks) {
528  buffer->num_chunks = (chunk + CHUNK_LIST_STEP) & ~(CHUNK_LIST_STEP - 1);
529  buffer->chunk_buffers = MEM_recallocN(buffer->chunk_buffers,
530  buffer->num_chunks * sizeof(void *));
531  buffer->chunk_ubos = MEM_recallocN(buffer->chunk_ubos, buffer->num_chunks * sizeof(void *));
532  BLI_BITMAP_RESIZE(buffer->chunk_used, buffer->num_chunks);
533  }
534 
535  char *chunk_buffer = buffer->chunk_buffers[chunk];
536 
537  if (chunk_buffer == NULL) {
538  buffer->chunk_buffers[chunk] = chunk_buffer = MEM_callocN(buffer->chunk_bytes, __func__);
539  }
540  else if (!BLI_BITMAP_TEST(buffer->chunk_used, chunk)) {
541  memset(chunk_buffer, 0, buffer->chunk_bytes);
542  }
543 
544  BLI_BITMAP_ENABLE(buffer->chunk_used, chunk);
545 
546  return chunk_buffer + buffer->item_size * item;
547 }
548 
551 /* -------------------------------------------------------------------- */
556 typedef struct DRWUniformAttrBuf {
557  /* Attribute list (also used as hash table key) handled by this buffer. */
559  /* Sparse UBO buffer containing the attribute values. */
561  /* Last handle used to update the buffer, checked for avoiding redundant updates. */
563  /* Linked list pointer used for freeing the empty unneeded buffers. */
566 
568 {
569  void **pkey, **pval;
570 
571  if (!BLI_ghash_ensure_p_ex(table, key, &pkey, &pval)) {
572  DRWUniformAttrBuf *buffer = MEM_callocN(sizeof(*buffer), __func__);
573 
574  *pkey = &buffer->key;
575  *pval = buffer;
576 
579  &buffer->ubos, key->count * sizeof(float[4]), DRW_RESOURCE_CHUNK_LEN);
580 
581  buffer->last_handle = (DRWResourceHandle)-1;
582  }
583 
584  return (DRWUniformAttrBuf *)*pval;
585 }
586 
587 /* This function mirrors lookup_property in cycles/blender/blender_object.cpp */
588 static bool drw_uniform_property_lookup(ID *id, const char *name, float r_data[4])
589 {
590  PointerRNA ptr, id_ptr;
591  PropertyRNA *prop;
592 
593  if (!id) {
594  return false;
595  }
596 
597  RNA_id_pointer_create(id, &id_ptr);
598 
599  if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) {
600  return false;
601  }
602 
603  if (prop == NULL) {
604  return false;
605  }
606 
608  int arraylen = RNA_property_array_length(&ptr, prop);
609 
610  if (arraylen == 0) {
611  float value;
612 
613  if (type == PROP_FLOAT) {
614  value = RNA_property_float_get(&ptr, prop);
615  }
616  else if (type == PROP_INT) {
617  value = RNA_property_int_get(&ptr, prop);
618  }
619  else {
620  return false;
621  }
622 
623  copy_v4_fl4(r_data, value, value, value, 1);
624  return true;
625  }
626 
627  if (type == PROP_FLOAT && arraylen <= 4) {
628  copy_v4_fl4(r_data, 0, 0, 0, 1);
629  RNA_property_float_get_array(&ptr, prop, r_data);
630  return true;
631  }
632 
633  return false;
634 }
635 
636 /* This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp */
638  Object *ob,
639  Object *dupli_parent,
640  DupliObject *dupli_source,
641  float r_data[4])
642 {
643  copy_v4_fl(r_data, 0);
644 
645  char idprop_name[(sizeof(attr->name) * 2) + 4];
646  {
647  char attr_name_esc[sizeof(attr->name) * 2];
648  BLI_str_escape(attr_name_esc, attr->name, sizeof(attr_name_esc));
649  SNPRINTF(idprop_name, "[\"%s\"]", attr_name_esc);
650  }
651 
652  /* If requesting instance data, check the parent particle system and object. */
653  if (attr->use_dupli) {
654  if (dupli_source && dupli_source->particle_system) {
655  ParticleSettings *settings = dupli_source->particle_system->part;
656  if (drw_uniform_property_lookup((ID *)settings, idprop_name, r_data) ||
657  drw_uniform_property_lookup((ID *)settings, attr->name, r_data)) {
658  return;
659  }
660  }
661  if (drw_uniform_property_lookup((ID *)dupli_parent, idprop_name, r_data) ||
662  drw_uniform_property_lookup((ID *)dupli_parent, attr->name, r_data)) {
663  return;
664  }
665  }
666 
667  /* Check the object and mesh. */
668  if (ob) {
669  if (drw_uniform_property_lookup((ID *)ob, idprop_name, r_data) ||
670  drw_uniform_property_lookup((ID *)ob, attr->name, r_data) ||
671  drw_uniform_property_lookup((ID *)ob->data, idprop_name, r_data) ||
672  drw_uniform_property_lookup((ID *)ob->data, attr->name, r_data)) {
673  return;
674  }
675  }
676 }
677 
680  DRWResourceHandle *handle,
681  Object *ob,
682  Object *dupli_parent,
683  DupliObject *dupli_source)
684 {
686 
687  if (buffer->last_handle != *handle) {
688  buffer->last_handle = *handle;
689 
690  int chunk = DRW_handle_chunk_get(handle);
691  int item = DRW_handle_id_get(handle);
692  float(*values)[4] = DRW_sparse_uniform_buffer_ensure_item(&buffer->ubos, chunk, item);
693 
694  LISTBASE_FOREACH (GPUUniformAttr *, attr, &buffer->key.list) {
695  drw_uniform_attribute_lookup(attr, ob, dupli_parent, dupli_source, *values++);
696  }
697  }
698 }
699 
701 {
703  return buffer ? &buffer->ubos : NULL;
704 }
705 
707 {
708  return GPU_uniform_attr_list_hash_new("obattr_hash");
709 }
710 
712 {
715  }
717 }
718 
720 {
722 
725  MEM_freeN(buffer);
726 }
727 
729 {
730  DRWUniformAttrBuf *remove_list = NULL;
731 
733  buffer->last_handle = (DRWResourceHandle)-1;
735 
737  buffer->next_empty = remove_list;
738  remove_list = buffer;
739  }
740  }
742 
743  while (remove_list) {
744  DRWUniformAttrBuf *buffer = remove_list;
745  remove_list = buffer->next_empty;
747  }
748 }
749 
751 {
753 }
754 
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
#define BLI_BITMAP_RESIZE(_bitmap, _num)
Definition: BLI_bitmap.h:117
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
Definition: bitmap.c:17
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
#define GHASH_FOREACH_END()
Definition: BLI_ghash.h:529
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
#define GHASH_FOREACH_BEGIN(type, var, what)
Definition: BLI_ghash.h:523
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:771
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void copy_v4_fl(float r[4], float f)
void(* MemblockValFreeFP)(void *val)
Definition: BLI_memblock.h:21
void BLI_memblock_destroy(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:66
#define BLI_memblock_create(elem_size)
Definition: BLI_memblock.h:32
void BLI_memblock_iternew(BLI_memblock *mblk, BLI_memblock_iter *iter) ATTR_NONNULL()
Definition: BLI_memblock.c:145
void * BLI_memblock_iterstep(BLI_memblock_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_memblock.c:157
void * BLI_memblock_alloc(BLI_memblock *mblk) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_memblock.c:115
void BLI_memblock_clear(BLI_memblock *mblk, MemblockValFreeFP free_callback) ATTR_NONNULL(1)
Definition: BLI_memblock.c:86
int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:434
void void BLI_mempool_clear_ex(BLI_mempool *pool, int totelem_reserve) ATTR_NONNULL(1)
Definition: BLI_mempool.c:650
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition: BLI_mempool.c:253
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition: BLI_mempool.c:319
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:707
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:250
unsigned int uint
Definition: BLI_sys_types.h:67
GPUBatch * GPU_batch_calloc(void)
Definition: gpu_batch.cc:36
GPUBatch
Definition: GPU_batch.h:78
void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src)
Definition: gpu_batch.cc:76
#define GPU_BATCH_INST_VBO_MAX_LEN
Definition: GPU_batch.h:21
#define GPU_BATCH_VBO_MAX_LEN
Definition: GPU_batch.h:20
void GPU_batch_clear(GPUBatch *)
Definition: gpu_batch.cc:87
#define GPU_BATCH_DISCARD_SAFE(batch)
Definition: GPU_batch.h:216
int GPU_batch_instbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo)
Definition: gpu_batch.cc:148
#define GPU_batch_init(batch, prim, verts, elem)
Definition: GPU_batch.h:96
@ GPU_BATCH_BUILDING
Definition: GPU_batch.h:44
_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 type
void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src)
struct GHash * GPU_uniform_attr_list_hash_new(const char *info)
void GPU_uniform_attr_list_free(GPUUniformAttrList *set)
GPUPrimType
Definition: GPU_primitive.h:18
struct GPUUniformBuf GPUUniformBuf
void GPU_uniformbuf_unbind(GPUUniformBuf *ubo)
#define GPU_uniformbuf_create(size)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
void GPU_uniformbuf_free(GPUUniformBuf *ubo)
void GPU_uniformbuf_bind(GPUUniformBuf *ubo, int slot)
uint GPU_vertbuf_get_vertex_alloc(const GPUVertBuf *verts)
struct GPUVertBuf GPUVertBuf
GPUVertBuf * GPU_vertbuf_calloc(void)
void GPU_vertbuf_handle_ref_remove(GPUVertBuf *verts)
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_init_with_format_ex(GPUVertBuf *, const GPUVertFormat *, GPUUsageType)
@ GPU_VERTBUF_DATA_UPLOADED
GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
void GPU_vertbuf_use(GPUVertBuf *)
void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len)
void GPU_vertbuf_handle_ref_add(GPUVertBuf *verts)
@ GPU_USAGE_DYNAMIC
void GPU_vertbuf_data_resize(GPUVertBuf *, uint v_len)
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
PropertyType
Definition: RNA_types.h:58
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_INT
Definition: RNA_types.h:60
static ListBase g_idatalists
static void drw_uniform_attribute_lookup(GPUUniformAttr *attr, Object *ob, Object *dupli_parent, DupliObject *dupli_source, float r_data[4])
void DRW_instance_data_list_free(DRWInstanceDataList *idatalist)
#define CHUNK_LIST_STEP
void * DRW_instance_data_next(DRWInstanceData *idata)
static bool drw_uniform_property_lookup(ID *id, const char *name, float r_data[4])
void * DRW_sparse_uniform_buffer_ensure_item(DRWSparseUniformBuf *buffer, int chunk, int item)
static DRWInstanceData * drw_instance_data_create(DRWInstanceDataList *idatalist, uint attr_size)
static void temp_buffer_handle_free(DRWTempBufferHandle *handle)
static void temp_instancing_handle_free(DRWTempInstancingHandle *handle)
void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist)
DRWInstanceDataList * DRW_instance_data_list_create(void)
bool DRW_sparse_uniform_buffer_is_empty(DRWSparseUniformBuf *buffer)
static void temp_batch_free(GPUBatch **batch)
DRWInstanceData * DRW_instance_data_request(DRWInstanceDataList *idatalist, uint attr_size)
DRWSparseUniformBuf * DRW_sparse_uniform_buffer_new(unsigned int item_size, unsigned int chunk_size)
static GPUUniformBuf * drw_sparse_uniform_buffer_get_ubo(DRWSparseUniformBuf *buffer, int chunk)
struct DRWTempBufferHandle DRWTempBufferHandle
void DRW_uniform_attrs_pool_flush_all(GHash *table)
struct DRWSparseUniformBuf DRWSparseUniformBuf
struct DRWUniformAttrBuf DRWUniformAttrBuf
static void DRW_instance_data_free(DRWInstanceData *idata)
GHash * DRW_uniform_attrs_pool_new()
void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist)
void DRW_sparse_uniform_buffer_free(DRWSparseUniformBuf *buffer)
GPUVertBuf * DRW_temp_buffer_request(DRWInstanceDataList *idatalist, GPUVertFormat *format, int *vert_len)
static DRWUniformAttrBuf * drw_uniform_attrs_pool_ensure(GHash *table, GPUUniformAttrList *key)
void DRW_uniform_attrs_pool_clear_all(GHash *table)
static void drw_uniform_attrs_pool_free_cb(void *ptr)
static void instancing_batch_references_add(GPUBatch *batch)
static void drw_sparse_uniform_buffer_init(DRWSparseUniformBuf *buffer, unsigned int item_size, unsigned int chunk_size)
DRWSparseUniformBuf * DRW_uniform_attrs_pool_find_ubo(GHash *table, struct GPUUniformAttrList *key)
void DRW_sparse_uniform_buffer_unbind(DRWSparseUniformBuf *buffer, int chunk)
GPUBatch * DRW_temp_batch_instance_request(DRWInstanceDataList *idatalist, GPUVertBuf *buf, GPUBatch *instancer, GPUBatch *geom)
void drw_uniform_attrs_pool_update(GHash *table, GPUUniformAttrList *key, DRWResourceHandle *handle, Object *ob, Object *dupli_parent, DupliObject *dupli_source)
GPUBatch * DRW_temp_batch_request(DRWInstanceDataList *idatalist, GPUVertBuf *buf, GPUPrimType prim_type)
void DRW_sparse_uniform_buffer_bind(DRWSparseUniformBuf *buffer, int chunk, int location)
struct DRWTempInstancingHandle DRWTempInstancingHandle
void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist)
void DRW_sparse_uniform_buffer_clear(DRWSparseUniformBuf *buffer, bool free_all)
void DRW_sparse_uniform_buffer_flush(DRWSparseUniformBuf *buffer)
static void instancing_batch_references_remove(GPUBatch *batch)
void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist)
void DRW_uniform_attrs_pool_free(GHash *table)
#define DRW_BUFFER_VERTS_CHUNK
#define MAX_INSTANCE_DATA_SIZE
BLI_INLINE uint32_t DRW_handle_chunk_get(const DRWResourceHandle *handle)
Definition: draw_manager.h:139
#define DRW_RESOURCE_CHUNK_LEN
Definition: draw_manager.h:116
BLI_INLINE uint32_t DRW_handle_id_get(const DRWResourceHandle *handle)
Definition: draw_manager.h:144
uint32_t DRWResourceHandle
Definition: draw_manager.h:132
struct @653::@655 batch
static uint attr_size(const GPUVertAttr *a)
ccl_global float * buffer
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static const int chunk_size
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1075
bool RNA_path_resolve(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_path.cc:503
struct DRWInstanceDataList * next
BLI_memblock * pool_batching
DRWInstanceData * idata_tail[MAX_INSTANCE_DATA_SIZE]
DRWInstanceData * idata_head[MAX_INSTANCE_DATA_SIZE]
struct DRWInstanceDataList * prev
BLI_memblock * pool_buffers
BLI_memblock * pool_instancing
struct DRWInstanceData * next
BLI_mempool * mempool
struct GPUUniformBuf ** chunk_ubos
GPUVertFormat * format
DRWSparseUniformBuf ubos
GPUUniformAttrList key
struct DRWUniformAttrBuf * next_empty
DRWResourceHandle last_handle
struct ParticleSystem * particle_system
Definition: BKE_duplilist.h:48
unsigned int count
Definition: GPU_material.h:321
Definition: DNA_ID.h:368
ParticleSettings * part
PointerRNA * ptr
Definition: wm_files.c:3480