Blender V5.0
draw_cache_extract_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2017 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "BKE_attribute.hh"
12
13#include "DNA_mesh_types.h"
14#include "DNA_scene_types.h"
15
16#include "BLI_map.hh"
17#include "BLI_set.hh"
18#include "BLI_task.hh"
19
20#include "GPU_capabilities.hh"
21#include "GPU_debug.hh"
22
23#include "draw_cache_extract.hh"
24#include "draw_subdivision.hh"
25
27
28// #define DEBUG_TIME
29
30#ifdef DEBUG_TIME
31# include "BLI_time_utildefines.h"
32#endif
33
34namespace blender::draw {
35
37 Span<IBOType> ibo_requests,
38 Span<VBOType> vbo_requests,
39 MeshBufferCache &cache)
40{
41 const bool request_face_normals = vbo_requests.contains(VBOType::CornerNormal) ||
42 vbo_requests.contains(VBOType::FaceDotNormal) ||
43 vbo_requests.contains(VBOType::EdgeFactor) ||
44 vbo_requests.contains(VBOType::MeshAnalysis);
45 const bool request_corner_normals = vbo_requests.contains(VBOType::CornerNormal);
46 const bool force_corner_normals = vbo_requests.contains(VBOType::Tangents);
47
48 if (request_face_normals) {
50 }
51 if ((request_corner_normals && mr.normals_domain == bke::MeshNormalDomain::Corner &&
53 force_corner_normals)
54 {
56 }
57
58 const bool calc_loose_geom = ibo_requests.contains(IBOType::Lines) ||
59 ibo_requests.contains(IBOType::LinesLoose) ||
60 ibo_requests.contains(IBOType::Points) ||
61 vbo_requests.contains(VBOType::Position) ||
62 vbo_requests.contains(VBOType::EditData) ||
63 vbo_requests.contains(VBOType::VertexNormal) ||
64 vbo_requests.contains(VBOType::IndexVert) ||
65 vbo_requests.contains(VBOType::IndexEdge) ||
66 vbo_requests.contains(VBOType::EdgeFactor);
67
68 if (calc_loose_geom) {
70 }
71}
72
74
75/* ---------------------------------------------------------------------- */
78
84static bool use_normals_simplify(const Scene &scene, const MeshRenderData &mr)
85{
86 if (!(scene.r.mode & R_SIMPLIFY) || !(scene.r.mode & R_SIMPLIFY_NORMALS)) {
87 return false;
88 }
89 if (!mr.mesh) {
90 return true;
91 }
92 const Mesh &mesh = *mr.mesh;
93 const std::optional<bke::AttributeMetaData> meta_data = mesh.attributes().lookup_meta_data(
94 "custom_normal");
95 if (!meta_data) {
96 return false;
97 }
98 if (meta_data->domain == bke::AttrDomain::Corner &&
99 meta_data->data_type == bke::AttrType::Int16_2D)
100 {
101 return true;
102 }
103 return false;
104}
105
107 const Scene &scene,
108 MeshBatchCache &cache,
109 MeshBufferCache &mbc,
110 const Span<IBOType> ibo_requests,
111 const Span<VBOType> vbo_requests,
112 Object &object,
113 Mesh &mesh,
114 const bool is_editmode,
115 const bool is_paint_mode,
116 const bool do_final,
117 const bool do_uvedit,
118 const bool use_hide)
119{
120 if (ibo_requests.is_empty() && vbo_requests.is_empty()) {
121 return;
122 }
123
125
126 Vector<IBOType, 16> ibos_to_create;
127 for (const IBOType request : ibo_requests) {
128 if (!buffers.ibos.contains(request)) {
129 ibos_to_create.append(request);
130 }
131 }
132
133 Vector<VBOType, 16> vbos_to_create;
134 for (const VBOType request : vbo_requests) {
135 if (!buffers.vbos.contains(request)) {
136 vbos_to_create.append(request);
137 }
138 }
139
140 if (ibos_to_create.is_empty() && vbos_to_create.is_empty()) {
141 return;
142 }
143
144#ifdef DEBUG_TIME
145 SCOPED_TIMER(__func__);
146#endif
147
149 object, mesh, is_editmode, is_paint_mode, do_final, do_uvedit, use_hide, scene.toolsettings);
150
151 mr.use_subsurf_fdots = mr.mesh && !mr.mesh->runtime->subsurf_face_dot_tags.is_empty();
153
154 ensure_dependency_data(mr, ibo_requests, vbo_requests, mbc);
155
156 Array<gpu::IndexBufPtr, 16> created_ibos(ibos_to_create.size());
157
158 {
159 /* Because lines and loose lines are stored in the same buffer, they're handled separately
160 * rather than from potentially multiple threads in the parallel_for_each loop below. */
161 const int lines_index = ibos_to_create.as_span().first_index_try(IBOType::Lines);
162 const int loose_lines_index = ibos_to_create.as_span().first_index_try(IBOType::LinesLoose);
163 if (lines_index != -1 || loose_lines_index != -1) {
164 extract_lines(mr,
165 lines_index == -1 ? nullptr : &created_ibos[lines_index],
166 loose_lines_index == -1 ? nullptr : &created_ibos[loose_lines_index],
167 cache.no_loose_wire);
168 }
169 }
170
171 threading::parallel_for_each(ibos_to_create.index_range(), [&](const int i) {
172 switch (ibos_to_create[i]) {
173 case IBOType::Tris:
174 created_ibos[i] = extract_tris(mr, mesh_render_data_faces_sorted_ensure(mr, mbc));
175 break;
176 case IBOType::Lines:
177 case IBOType::LinesLoose:
178 /* Handled as a special case above. */
179 break;
180 case IBOType::Points:
181 created_ibos[i] = extract_points(mr);
182 break;
183 case IBOType::FaceDots:
184 created_ibos[i] = extract_face_dots(mr);
185 break;
186 case IBOType::LinesPaintMask:
187 created_ibos[i] = extract_lines_paint_mask(mr);
188 break;
189 case IBOType::LinesAdjacency:
190 created_ibos[i] = extract_lines_adjacency(mr, cache.is_manifold);
191 break;
192 case IBOType::UVTris:
193 created_ibos[i] = extract_edituv_tris(mr, false);
194 break;
195 case IBOType::EditUVTris:
196 created_ibos[i] = extract_edituv_tris(mr, true);
197 break;
198 case IBOType::AllUVLines:
199 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::All);
200 break;
201 case IBOType::UVLines:
202 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Selection);
203 break;
204 case IBOType::EditUVLines:
205 created_ibos[i] = extract_edituv_lines(mr, UvExtractionMode::Edit);
206 break;
207 case IBOType::EditUVPoints:
208 created_ibos[i] = extract_edituv_points(mr);
209 break;
210 case IBOType::EditUVFaceDots:
211 created_ibos[i] = extract_edituv_face_dots(mr);
212 break;
213 }
214 });
215
216 Array<gpu::VertBufPtr, 16> created_vbos(vbos_to_create.size());
217
218 const bool do_hq_normals = (scene.r.perf_flag & SCE_PERF_HQ_NORMALS) != 0 ||
220
221 threading::parallel_for_each(vbos_to_create.index_range(), [&](const int i) {
222 switch (vbos_to_create[i]) {
223 case VBOType::Position:
224 created_vbos[i] = extract_positions(mr);
225 break;
226 case VBOType::CornerNormal:
227 created_vbos[i] = extract_normals(mr, do_hq_normals);
228 break;
229 case VBOType::EdgeFactor:
230 created_vbos[i] = extract_edge_factor(mr);
231 break;
232 case VBOType::VertexGroupWeight:
233 created_vbos[i] = extract_weights(mr, cache);
234 break;
235 case VBOType::UVs:
236 created_vbos[i] = extract_uv_maps(mr, cache);
237 break;
238 case VBOType::Tangents:
239 created_vbos[i] = extract_tangents(mr, cache, do_hq_normals);
240 break;
241 case VBOType::SculptData:
242 created_vbos[i] = extract_sculpt_data(mr);
243 break;
244 case VBOType::Orco:
245 created_vbos[i] = extract_orco(mr);
246 break;
247 case VBOType::EditData:
248 created_vbos[i] = extract_edit_data(mr);
249 break;
250 case VBOType::EditUVData:
251 created_vbos[i] = extract_edituv_data(mr);
252 break;
253 case VBOType::EditUVStretchArea:
254 created_vbos[i] = extract_edituv_stretch_area(mr, cache.tot_area, cache.tot_uv_area);
255 break;
256 case VBOType::EditUVStretchAngle:
257 created_vbos[i] = extract_edituv_stretch_angle(mr);
258 break;
259 case VBOType::MeshAnalysis:
260 created_vbos[i] = extract_mesh_analysis(mr, object.object_to_world());
261 break;
262 case VBOType::FaceDotPosition:
263 created_vbos[i] = extract_face_dots_position(mr);
264 break;
265 case VBOType::FaceDotNormal:
266 created_vbos[i] = extract_face_dot_normals(mr, do_hq_normals);
267 break;
268 case VBOType::FaceDotUV:
269 created_vbos[i] = extract_face_dots_uv(mr);
270 break;
271 case VBOType::FaceDotEditUVData:
272 created_vbos[i] = extract_face_dots_edituv_data(mr);
273 break;
274 case VBOType::SkinRoots:
275 created_vbos[i] = extract_skin_roots(mr);
276 break;
277 case VBOType::IndexVert:
278 created_vbos[i] = extract_vert_index(mr);
279 break;
280 case VBOType::IndexEdge:
281 created_vbos[i] = extract_edge_index(mr);
282 break;
283 case VBOType::IndexFace:
284 created_vbos[i] = extract_face_index(mr);
285 break;
286 case VBOType::IndexFaceDot:
287 created_vbos[i] = extract_face_dot_index(mr);
288 break;
289 case VBOType::Attr0:
290 case VBOType::Attr1:
291 case VBOType::Attr2:
292 case VBOType::Attr3:
293 case VBOType::Attr5:
294 case VBOType::Attr6:
295 case VBOType::Attr7:
296 case VBOType::Attr8:
297 case VBOType::Attr9:
298 case VBOType::Attr10:
299 case VBOType::Attr11:
300 case VBOType::Attr12:
301 case VBOType::Attr13:
302 case VBOType::Attr14:
303 case VBOType::Attr15: {
304 const int8_t attr_index = int8_t(vbos_to_create[i]) - int8_t(VBOType::Attr0);
305 created_vbos[i] = extract_attribute(mr, cache.attr_used[attr_index]);
306 break;
307 }
308 case VBOType::AttrViewer:
309 created_vbos[i] = extract_attr_viewer(mr);
310 break;
311 case VBOType::VertexNormal:
312 created_vbos[i] = extract_vert_normals(mr);
313 break;
314 case VBOType::PaintOverlayFlag:
315 created_vbos[i] = extract_paint_overlay_flags(mr);
316 break;
317 }
318 });
319
320 for (const int i : ibos_to_create.index_range()) {
321 buffers.ibos.add_new(ibos_to_create[i], std::move(created_ibos[i]));
322 }
323 for (const int i : vbos_to_create.index_range()) {
324 buffers.vbos.add_new(vbos_to_create[i], std::move(created_vbos[i]));
325 }
326}
327
329
330/* ---------------------------------------------------------------------- */
333
335 MeshBufferCache &mbc,
336 const Span<IBOType> ibo_requests,
337 const Span<VBOType> vbo_requests,
338 DRWSubdivCache &subdiv_cache,
339 MeshRenderData &mr)
340{
341 if (ibo_requests.is_empty() && vbo_requests.is_empty()) {
342 return;
343 }
345
348 DRW_subdivide_loose_geom(subdiv_cache, mbc);
349
350 Set<IBOType, 16> ibos_to_create;
351 for (const IBOType request : ibo_requests) {
352 if (!buffers.ibos.contains(request)) {
353 ibos_to_create.add_new(request);
354 }
355 }
356
357 Set<VBOType, 16> vbos_to_create;
358 for (const VBOType request : vbo_requests) {
359 if (!buffers.vbos.contains(request)) {
360 vbos_to_create.add_new(request);
361 }
362 }
363
364 if (ibos_to_create.is_empty() && vbos_to_create.is_empty()) {
365 return;
366 }
367
368 static gpu::DebugScope subdiv_extract_scope = {"SubdivExtraction"};
369 auto capture = subdiv_extract_scope.scoped_capture();
370
371 if (vbos_to_create.contains(VBOType::Position) || vbos_to_create.contains(VBOType::Orco)) {
372 gpu::VertBufPtr orco_vbo;
373 /* Don't use `add_new` because #VBOType::Orco might be requested after #VBOType::Position
374 * already exists. It's inefficient to build the position VBO a second time but that's the API
375 * that GPU subdivision provides. */
376 buffers.vbos.add(
379 subdiv_cache, mr, vbos_to_create.contains(VBOType::Orco) ? &orco_vbo : nullptr));
380 if (orco_vbo) {
381 buffers.vbos.add_new(VBOType::Orco, std::move(orco_vbo));
382 }
383 }
384 if (vbos_to_create.contains(VBOType::CornerNormal)) {
385 /* The corner normals calculation uses positions and normals stored in the `pos` VBO. */
386 buffers.vbos.add_new(
388 extract_normals_subdiv(mr, subdiv_cache, *buffers.vbos.lookup(VBOType::Position)));
389 }
390 if (vbos_to_create.contains(VBOType::EdgeFactor)) {
391 buffers.vbos.add_new(
393 extract_edge_factor_subdiv(subdiv_cache, mr, *buffers.vbos.lookup(VBOType::Position)));
394 }
395 if (ibos_to_create.contains(IBOType::Lines) || ibos_to_create.contains(IBOType::LinesLoose)) {
396 gpu::IndexBufPtr lines_ibo;
397 gpu::IndexBufPtr lines_loose_ibo;
398 extract_lines_subdiv(subdiv_cache,
399 mr,
400 ibos_to_create.contains(IBOType::Lines) ? &lines_ibo : nullptr,
401 ibos_to_create.contains(IBOType::LinesLoose) ? &lines_loose_ibo : nullptr,
402 cache.no_loose_wire);
403 if (lines_ibo) {
404 buffers.ibos.add_new(IBOType::Lines, std::move(lines_ibo));
405 }
406 if (lines_loose_ibo) {
407 buffers.ibos.add_new(IBOType::LinesLoose, std::move(lines_loose_ibo));
408 }
409 }
410 if (ibos_to_create.contains(IBOType::Tris)) {
411 buffers.ibos.add_new(IBOType::Tris, extract_tris_subdiv(subdiv_cache, cache));
412 }
413 if (ibos_to_create.contains(IBOType::Points)) {
414 buffers.ibos.add_new(IBOType::Points, extract_points_subdiv(mr, subdiv_cache));
415 }
416 if (vbos_to_create.contains(VBOType::EditData)) {
417 buffers.vbos.add_new(VBOType::EditData, extract_edit_data_subdiv(mr, subdiv_cache));
418 }
419 if (vbos_to_create.contains(VBOType::Tangents)) {
420 buffers.vbos.add_new(VBOType::Tangents, extract_tangents_subdiv(mr, subdiv_cache, cache));
421 }
422 if (vbos_to_create.contains(VBOType::IndexVert)) {
423 buffers.vbos.add_new(VBOType::IndexVert, extract_vert_index_subdiv(subdiv_cache, mr));
424 }
425 if (vbos_to_create.contains(VBOType::IndexEdge)) {
426 buffers.vbos.add_new(VBOType::IndexEdge, extract_edge_index_subdiv(subdiv_cache, mr));
427 }
428 if (vbos_to_create.contains(VBOType::IndexFace)) {
429 buffers.vbos.add_new(VBOType::IndexFace, extract_face_index_subdiv(subdiv_cache, mr));
430 }
431 if (vbos_to_create.contains(VBOType::VertexGroupWeight)) {
433 extract_weights_subdiv(mr, subdiv_cache, cache));
434 }
435 if (vbos_to_create.contains(VBOType::FaceDotNormal) ||
436 vbos_to_create.contains(VBOType::FaceDotPosition) ||
437 ibos_to_create.contains(IBOType::FaceDots))
438 {
439 gpu::VertBufPtr face_dot_position_vbo;
440 gpu::VertBufPtr face_dot_normal_vbo;
441 gpu::IndexBufPtr face_dot_ibo;
442
443 /* We use only one extractor for face dots, as the work is done in a single compute shader. */
445 subdiv_cache,
446 face_dot_position_vbo,
447 vbos_to_create.contains(VBOType::FaceDotNormal) ? &face_dot_normal_vbo : nullptr,
448 face_dot_ibo);
449 if (vbos_to_create.contains(VBOType::FaceDotPosition)) {
450 buffers.vbos.add_new(VBOType::FaceDotPosition, std::move(face_dot_position_vbo));
451 }
452 if (face_dot_normal_vbo) {
453 buffers.vbos.add_new(VBOType::FaceDotNormal, std::move(face_dot_normal_vbo));
454 }
455 if (ibos_to_create.contains(IBOType::FaceDots)) {
456 buffers.ibos.add_new(IBOType::FaceDots, std::move(face_dot_ibo));
457 }
458 }
459 if (vbos_to_create.contains(VBOType::PaintOverlayFlag)) {
461 extract_paint_overlay_flags_subdiv(mr, subdiv_cache));
462 }
463 if (ibos_to_create.contains(IBOType::LinesPaintMask)) {
464 buffers.ibos.add_new(IBOType::LinesPaintMask,
465 extract_lines_paint_mask_subdiv(mr, subdiv_cache));
466 }
467 if (ibos_to_create.contains(IBOType::LinesAdjacency)) {
468 buffers.ibos.add_new(IBOType::LinesAdjacency,
469 extract_lines_adjacency_subdiv(subdiv_cache, cache.is_manifold));
470 }
471 if (vbos_to_create.contains(VBOType::SculptData)) {
472 buffers.vbos.add_new(VBOType::SculptData, extract_sculpt_data_subdiv(mr, subdiv_cache));
473 }
474 if (vbos_to_create.contains(VBOType::UVs)) {
475 /* Make sure UVs are computed before edituv stuffs. */
476 buffers.vbos.add_new(VBOType::UVs, extract_uv_maps_subdiv(subdiv_cache, cache));
477 }
478 if (ibos_to_create.contains(IBOType::AllUVLines)) {
479 buffers.ibos.add_new(IBOType::AllUVLines,
481 }
482 if (ibos_to_create.contains(IBOType::UVLines)) {
483 buffers.ibos.add_new(
486 }
487 if (vbos_to_create.contains(VBOType::EditUVStretchArea)) {
488 buffers.vbos.add_new(
490 extract_edituv_stretch_area_subdiv(mr, subdiv_cache, cache.tot_area, cache.tot_uv_area));
491 }
492 if (vbos_to_create.contains(VBOType::EditUVStretchAngle)) {
494 extract_edituv_stretch_angle_subdiv(mr, subdiv_cache, cache));
495 }
496 if (vbos_to_create.contains(VBOType::EditUVData)) {
497 buffers.vbos.add_new(VBOType::EditUVData, extract_edituv_data_subdiv(mr, subdiv_cache));
498 }
499 if (ibos_to_create.contains(IBOType::EditUVTris)) {
500 buffers.ibos.add_new(IBOType::EditUVTris, extract_edituv_tris_subdiv(mr, subdiv_cache));
501 }
502 if (ibos_to_create.contains(IBOType::EditUVLines)) {
503 buffers.ibos.add_new(IBOType::EditUVLines,
505 }
506 if (ibos_to_create.contains(IBOType::EditUVPoints)) {
507 buffers.ibos.add_new(IBOType::EditUVPoints, extract_edituv_points_subdiv(mr, subdiv_cache));
508 }
509 for (const int8_t i : IndexRange(GPU_MAX_ATTR)) {
510 const VBOType request = VBOType(int8_t(VBOType::Attr0) + i);
511 if (vbos_to_create.contains(request)) {
512 buffers.vbos.add_new(request,
513 extract_attribute_subdiv(mr, subdiv_cache, cache.attr_used[i]));
514 }
515 }
516}
517
519
520} // namespace blender::draw
Utility defines for timing/benchmarks.
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:70
@ SCE_PERF_HQ_NORMALS
@ R_SIMPLIFY
@ R_SIMPLIFY_NORMALS
bool GPU_use_hq_normals_workaround()
static constexpr int GPU_MAX_ATTR
Definition GPU_shader.hh:33
AttributeSet attributes
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool is_empty() const
Definition BLI_set.hh:595
void add_new(const Key &key)
Definition BLI_set.hh:233
constexpr bool is_empty() const
Definition BLI_span.hh:260
constexpr bool contains(const T &value) const
Definition BLI_span.hh:277
int64_t size() const
void append(const T &value)
bool is_empty() const
IndexRange index_range() const
Span< T > as_span() const
Extraction of Mesh data into VBO to feed to GPU.
void mesh_render_data_update_face_normals(MeshRenderData &mr)
gpu::VertBufPtr extract_attribute_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, StringRef name)
gpu::IndexBufPtr extract_lines_adjacency_subdiv(const DRWSubdivCache &subdiv_cache, bool &r_is_manifold)
gpu::VertBufPtr extract_edit_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
static void ensure_dependency_data(MeshRenderData &mr, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, MeshBufferCache &cache)
gpu::IndexBufPtr extract_edituv_lines_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, UvExtractionMode mode)
gpu::IndexBufPtr extract_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_tangents_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
gpu::VertBufPtr extract_edituv_stretch_angle_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCache &cache)
gpu::VertBufPtr extract_vert_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
gpu::VertBufPtr extract_sculpt_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::IndexBufPtr extract_edituv_tris_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
void extract_lines(const MeshRenderData &mr, gpu::IndexBufPtr *lines, gpu::IndexBufPtr *lines_loose, bool &no_loose_wire)
gpu::VertBufPtr extract_positions_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBufPtr *orco_vbo)
gpu::IndexBufPtr extract_edituv_points_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_face_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, DRWSubdivCache &subdiv_cache, MeshRenderData &mr)
gpu::VertBufPtr extract_edge_index_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr)
gpu::VertBufPtr extract_paint_overlay_flags_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::IndexBufPtr extract_tris_subdiv(const DRWSubdivCache &subdiv_cache, MeshBatchCache &cache)
void mesh_render_data_update_corner_normals(MeshRenderData &mr)
void extract_face_dots_subdiv(const DRWSubdivCache &subdiv_cache, gpu::VertBufPtr &fdots_pos, gpu::VertBufPtr *fdots_nor, gpu::IndexBufPtr &fdots)
gpu::VertBufPtr extract_edge_factor_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::VertBuf &pos)
gpu::VertBufPtr extract_normals_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, gpu::VertBuf &pos)
void mesh_buffer_cache_create_requested(TaskGraph &task_graph, const Scene &scene, MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, Object &object, Mesh &mesh, bool is_editmode, bool is_paint_mode, bool do_final, bool do_uvedit, bool use_hide)
gpu::VertBufPtr extract_weights_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
static bool use_normals_simplify(const Scene &scene, const MeshRenderData &mr)
gpu::VertBufPtr extract_edituv_stretch_area_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache, float &tot_area, float &tot_uv_area)
MeshRenderData mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
void mesh_render_data_update_loose_geom(MeshRenderData &mr, MeshBufferCache &cache)
gpu::IndexBufPtr extract_lines_paint_mask_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
gpu::VertBufPtr extract_uv_maps_subdiv(const DRWSubdivCache &subdiv_cache, const MeshBatchCache &cache)
gpu::VertBufPtr extract_edituv_data_subdiv(const MeshRenderData &mr, const DRWSubdivCache &subdiv_cache)
void extract_lines_subdiv(const DRWSubdivCache &subdiv_cache, const MeshRenderData &mr, gpu::IndexBufPtr *lines, gpu::IndexBufPtr *lines_loose, bool &no_loose_wire)
std::unique_ptr< IndexBuf, IndexBufDeleter > IndexBufPtr
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
void parallel_for_each(Range &&range, const Function &function)
Definition BLI_task.hh:56
MeshRuntimeHandle * runtime
struct ToolSettings * toolsettings
struct RenderData r
VectorSet< std::string > attr_used
bke::MeshNormalDomain normals_domain
ScopedCapture scoped_capture()
Definition GPU_debug.hh:149
i
Definition text_draw.cc:230
char * buffers[2]