Blender  V3.3
extract_mesh_ibo_tris.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "extract_mesh.hh"
11 
12 #include "draw_subdivision.h"
13 
14 namespace blender::draw {
15 
16 static void extract_tris_mat_task_reduce(void *_userdata_to, void *_userdata_from)
17 {
18  GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
19  GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
20  GPU_indexbuf_join(elb_to, elb_from);
21 }
22 
23 /* ---------------------------------------------------------------------- */
27 static void extract_tris_init(const MeshRenderData *mr,
28  MeshBatchCache *UNUSED(cache),
29  void *UNUSED(ibo),
30  void *tls_data)
31 {
32  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
34 }
35 
37  const BMFace *f,
38  const int f_index,
39  void *_data)
40 {
41  int tri_first_index = mr->poly_sorted.tri_first_index[f_index];
42  if (tri_first_index == -1) {
43  return;
44  }
45 
46  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
47  int tri_first_index_real = poly_to_tri_count(f_index, BM_elem_index_get(f->l_first));
48 
49  struct BMLoop *(*looptris)[3] = mr->edit_bmesh->looptris;
50  int tri_len = f->len - 2;
51  for (int offs = 0; offs < tri_len; offs++) {
52  BMLoop **elt = looptris[tri_first_index_real + offs];
53  int tri_index = tri_first_index + offs;
55  tri_index,
56  BM_elem_index_get(elt[0]),
57  BM_elem_index_get(elt[1]),
58  BM_elem_index_get(elt[2]));
59  }
60 }
61 
63  const MPoly *mp,
64  const int mp_index,
65  void *_data)
66 {
67  int tri_first_index = mr->poly_sorted.tri_first_index[mp_index];
68  if (tri_first_index == -1) {
69  return;
70  }
71 
72  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
73  int tri_first_index_real = poly_to_tri_count(mp_index, mp->loopstart);
74 
75  int tri_len = mp->totloop - 2;
76  for (int offs = 0; offs < tri_len; offs++) {
77  const MLoopTri *mlt = &mr->mlooptri[tri_first_index_real + offs];
78  int tri_index = tri_first_index + offs;
79  GPU_indexbuf_set_tri_verts(elb, tri_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
80  }
81 }
82 
83 static void extract_tris_finish(const MeshRenderData *mr,
84  MeshBatchCache *cache,
85  void *buf,
86  void *_data)
87 {
88  GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
89  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
91 
92  /* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch
93  * is created before the surfaces-per-material. */
94  if (mr->use_final_mesh && cache->tris_per_mat) {
95  int mat_start = 0;
96  for (int i = 0; i < mr->mat_len; i++) {
97  /* These IBOs have not been queried yet but we create them just in case they are needed
98  * later since they are not tracked by mesh_buffer_cache_create_requested(). */
99  if (cache->tris_per_mat[i] == nullptr) {
100  cache->tris_per_mat[i] = GPU_indexbuf_calloc();
101  }
102  const int mat_tri_len = mr->poly_sorted.mat_tri_len[i];
103  /* Multiply by 3 because these are triangle indices. */
104  const int start = mat_start * 3;
105  const int len = mat_tri_len * 3;
107  mat_start += mat_tri_len;
108  }
109  }
110 }
111 
112 static void extract_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
113  const MeshRenderData *UNUSED(mr),
114  MeshBatchCache *cache,
115  void *buffer,
116  void *UNUSED(data))
117 {
118  GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer);
119  /* Initialize the index buffer, it was already allocated, it will be filled on the device. */
121 
122  if (cache->tris_per_mat) {
123  for (int i = 0; i < cache->mat_len; i++) {
124  if (cache->tris_per_mat[i] == nullptr) {
125  cache->tris_per_mat[i] = GPU_indexbuf_calloc();
126  }
127 
128  /* Multiply by 6 since we have 2 triangles per quad. */
129  const int start = subdiv_cache->mat_start[i] * 6;
130  const int len = (subdiv_cache->mat_end[i] - subdiv_cache->mat_start[i]) * 6;
132  }
133  }
134 
135  draw_subdiv_build_tris_buffer(subdiv_cache, ibo, cache->mat_len);
136 }
137 
139 {
140  MeshExtract extractor = {nullptr};
141  extractor.init = extract_tris_init;
146  extractor.finish = extract_tris_finish;
148  extractor.data_size = sizeof(GPUIndexBufBuilder);
149  extractor.use_threading = true;
150  extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.tris);
151  return extractor;
152 }
153 
160  MeshBatchCache *UNUSED(cache),
161  void *UNUSED(ibo),
162  void *tls_data)
163 {
164  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
166 }
167 
169  BMLoop **elt,
170  const int elt_index,
171  void *_data)
172 {
173  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
174  if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
176  elt_index,
177  BM_elem_index_get(elt[0]),
178  BM_elem_index_get(elt[1]),
179  BM_elem_index_get(elt[2]));
180  }
181  else {
182  GPU_indexbuf_set_tri_restart(elb, elt_index);
183  }
184 }
185 
187  const MLoopTri *mlt,
188  const int mlt_index,
189  void *_data)
190 {
191  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
192  const MPoly *mp = &mr->mpoly[mlt->poly];
193  if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
194  GPU_indexbuf_set_tri_verts(elb, mlt_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
195  }
196  else {
197  GPU_indexbuf_set_tri_restart(elb, mlt_index);
198  }
199 }
200 
202  MeshBatchCache *cache,
203  void *buf,
204  void *_data)
205 {
206  GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
207  GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
208  GPU_indexbuf_build_in_place(elb, ibo);
209 
210  /* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch
211  * is created before the surfaces-per-material. */
212  if (mr->use_final_mesh && cache->tris_per_mat) {
213  for (int i = 0; i < mr->mat_len; i++) {
214  /* These IBOs have not been queried yet but we create them just in case they are needed
215  * later since they are not tracked by mesh_buffer_cache_create_requested(). */
216  if (cache->tris_per_mat[i] == nullptr) {
217  cache->tris_per_mat[i] = GPU_indexbuf_calloc();
218  }
219  /* Multiply by 3 because these are triangle indices. */
220  const int len = mr->tri_len * 3;
222  }
223  }
224 }
225 
227 {
228  MeshExtract extractor = {nullptr};
235  extractor.data_type = MR_DATA_NONE;
236  extractor.data_size = sizeof(GPUIndexBufBuilder);
237  extractor.use_threading = true;
238  extractor.mesh_buffer_offset = offsetof(MeshBufferList, ibo.tris);
239  return extractor;
240 }
241 
244 } // namespace blender::draw
245 
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
#define UNUSED(x)
@ ME_HIDE
struct GPUIndexBufBuilder GPUIndexBufBuilder
struct GPUIndexBuf GPUIndexBuf
void GPU_indexbuf_init(GPUIndexBufBuilder *, GPUPrimType, uint prim_len, uint vertex_len)
void GPU_indexbuf_init_build_on_device(GPUIndexBuf *elem, uint index_len)
void GPU_indexbuf_join(GPUIndexBufBuilder *builder, const GPUIndexBufBuilder *builder_from)
void GPU_indexbuf_set_tri_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, uint v2, uint v3)
void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem)
GPUIndexBuf * GPU_indexbuf_calloc(void)
void GPU_indexbuf_create_subrange_in_place(GPUIndexBuf *elem, GPUIndexBuf *elem_src, uint start, uint length)
void GPU_indexbuf_build_in_place(GPUIndexBufBuilder *, GPUIndexBuf *)
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
Read Guarded memory(de)allocation.
@ BM_ELEM_HIDDEN
Definition: bmesh_class.h:472
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:110
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
@ MR_DATA_NONE
@ MR_DATA_POLYS_SORTED
@ MR_DATA_LOOPTRI
void draw_subdiv_build_tris_buffer(const DRWSubdivCache *cache, GPUIndexBuf *subdiv_tris, const int material_count)
int len
Definition: draw_manager.c:108
Extraction of Mesh data into VBO to feed to GPU.
const MeshExtract extract_tris_single_mat
const MeshExtract extract_tris
ccl_global float * buffer
static void extract_tris_single_mat_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *UNUSED(ibo), void *tls_data)
static void extract_tris_init_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *UNUSED(mr), MeshBatchCache *cache, void *buffer, void *UNUSED(data))
static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr, const MLoopTri *mlt, const int mlt_index, void *_data)
constexpr MeshExtract create_extractor_tris()
static void extract_tris_iter_poly_mesh(const MeshRenderData *mr, const MPoly *mp, const int mp_index, void *_data)
static void extract_tris_iter_poly_bm(const MeshRenderData *mr, const BMFace *f, const int f_index, void *_data)
static void extract_tris_init(const MeshRenderData *mr, MeshBatchCache *UNUSED(cache), void *UNUSED(ibo), void *tls_data)
static void extract_tris_single_mat_finish(const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *_data)
static void extract_tris_single_mat_iter_looptri_bm(const MeshRenderData *UNUSED(mr), BMLoop **elt, const int elt_index, void *_data)
static void extract_tris_finish(const MeshRenderData *mr, MeshBatchCache *cache, void *buf, void *_data)
constexpr MeshExtract create_extractor_tris_single_mat()
static void extract_tris_mat_task_reduce(void *_userdata_to, void *_userdata_from)
struct BMLoop *(* looptris)[3]
Definition: BKE_editmesh.h:48
int len
Definition: bmesh_class.h:267
BMLoop * l_first
Definition: bmesh_class.h:261
struct BMFace * f
Definition: bmesh_class.h:171
unsigned int poly
unsigned int tri[3]
GPUIndexBuf ** tris_per_mat
GPUIndexBuf * tris
size_t mesh_buffer_offset
eMRDataType data_type
ExtractFinishFn * finish
ExtractInitSubdivFn * init_subdiv
size_t data_size
ExtractTriBMeshFn * iter_looptri_bm
ExtractPolyBMeshFn * iter_poly_bm
ExtractPolyMeshFn * iter_poly_mesh
ExtractTaskReduceFn * task_reduce
ExtractTriMeshFn * iter_looptri_mesh
bool use_threading
ExtractInitFn * init
const MPoly * mpoly
Definition: extract_mesh.hh:77
MLoopTri * mlooptri
Definition: extract_mesh.hh:83
struct MeshRenderData::@319 poly_sorted
BMEditMesh * edit_bmesh
Definition: extract_mesh.hh:55
int * tri_first_index
Definition: extract_mesh.hh:93