62static const GPUVertFormat &get_patch_handle_format()
64 static const GPUVertFormat
format = [&]() {
75static const GPUVertFormat &get_quadtree_format()
77 static const GPUVertFormat
format = [&]() {
85struct CompressedPatchCoord {
91MINLINE CompressedPatchCoord make_patch_coord(
int ptex_face_index,
float u,
float v)
93 CompressedPatchCoord patch_coord = {
95 (
uint(u * 65535.0f) << 16) |
uint(
v * 65535.0f),
101static const GPUVertFormat &get_blender_patch_coords_format()
103 static const GPUVertFormat
format = [&]() {
143 const uint32_t number_of_quads = number_of_loops / 4;
144 return number_of_quads * 2;
159 buffer->data<
int32_t>().take_front(num_loops).copy_from({vert_origindex, num_loops});
174#ifdef WITH_OPENSUBDIV
184 int min_patch_face = 0;
185 int max_patch_face = 0;
187 int patches_are_triangular = 0;
195 &patches_are_triangular);
197 gpu_patch_map->patch_map_handles = patch_map_handles;
198 gpu_patch_map->patch_map_quadtree = patch_map_quadtree;
199 gpu_patch_map->min_patch_face = min_patch_face;
200 gpu_patch_map->max_patch_face = max_patch_face;
201 gpu_patch_map->max_depth = max_depth;
202 gpu_patch_map->patches_are_triangular = patches_are_triangular;
277#define SUBDIV_COARSE_FACE_FLAG_SMOOTH 1u
278#define SUBDIV_COARSE_FACE_FLAG_SELECT 2u
279#define SUBDIV_COARSE_FACE_FLAG_ACTIVE 4u
280#define SUBDIV_COARSE_FACE_FLAG_HIDDEN 8u
282#define SUBDIV_COARSE_FACE_FLAG_OFFSET 28u
284#define SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK \
285 (SUBDIV_COARSE_FACE_FLAG_SMOOTH << SUBDIV_COARSE_FACE_FLAG_OFFSET)
286#define SUBDIV_COARSE_FACE_FLAG_SELECT_MASK \
287 (SUBDIV_COARSE_FACE_FLAG_SELECT << SUBDIV_COARSE_FACE_FLAG_OFFSET)
288#define SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK \
289 (SUBDIV_COARSE_FACE_FLAG_ACTIVE << SUBDIV_COARSE_FACE_FLAG_OFFSET)
290#define SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK \
291 (SUBDIV_COARSE_FACE_FLAG_HIDDEN << SUBDIV_COARSE_FACE_FLAG_OFFSET)
293#define SUBDIV_COARSE_FACE_LOOP_START_MASK \
294 ~((SUBDIV_COARSE_FACE_FLAG_SMOOTH | SUBDIV_COARSE_FACE_FLAG_SELECT | \
295 SUBDIV_COARSE_FACE_FLAG_ACTIVE | SUBDIV_COARSE_FACE_FLAG_HIDDEN) \
296 << SUBDIV_COARSE_FACE_FLAG_OFFSET)
336 for (
const int i :
faces.index_range()) {
364 for (
const int i :
faces.index_range()) {
414 if (subdiv_cache ==
nullptr) {
415 subdiv_cache = MEM_new<DRWSubdivCache>(__func__);
418 return *subdiv_cache;
421#ifdef WITH_OPENSUBDIV
456struct DRWCacheBuildingContext {
457 const Mesh *coarse_mesh;
458 const bke::subdiv::Subdiv *subdiv;
459 const bke::subdiv::ToMeshSettings *settings;
461 DRWSubdivCache *cache;
464 CompressedPatchCoord *patch_coords;
465 int *subdiv_loop_vert_index;
466 int *subdiv_loop_subdiv_vert_index;
467 int *subdiv_loop_edge_index;
468 int *subdiv_loop_edge_draw_flag;
469 int *subdiv_loop_subdiv_edge_index;
470 int *subdiv_loop_face_index;
473 int *vert_origindex_map;
474 int *edge_draw_flag_map;
475 int *edge_origindex_map;
480 const int *orig_index_vert;
481 const int *orig_index_edge;
484static bool draw_subdiv_topology_info_cb(
const bke::subdiv::ForeachContext *foreach_context,
489 const int *subdiv_face_offset)
493 if (num_verts == 0 && num_loops == 0) {
497 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
501 if (num_loops != 0) {
502 cache->num_subdiv_edges =
uint(num_edges);
503 cache->num_subdiv_loops =
uint(num_loops);
504 cache->num_subdiv_verts =
uint(num_verts);
505 cache->num_subdiv_quads =
uint(num_faces);
506 cache->subdiv_face_offset =
static_cast<int *
>(
MEM_dupallocN(subdiv_face_offset));
509 cache->may_have_loose_geom = num_verts != 0 || num_edges != 0;
524 *cache->corner_patch_coords, get_blender_patch_coords_format(),
GPU_USAGE_DYNAMIC);
543 "subdiv_loop_subdiv_vert_index");
546 "subdiv_loop_subdiv_edge_index");
549 "subdiv_loop_face_index");
552 ctx->patch_coords = cache->patch_coords->data<CompressedPatchCoord>().
data();
553 ctx->subdiv_loop_vert_index = cache->verts_orig_index->data<
int>().
data();
554 ctx->subdiv_loop_edge_index = cache->edges_orig_index->data<
int>().
data();
555 ctx->subdiv_loop_edge_draw_flag = cache->edges_draw_flag->data<
int>().
data();
556 ctx->subdiv_loop_subdiv_vert_index = cache->subdiv_loop_subdiv_vert_index;
557 ctx->subdiv_loop_subdiv_edge_index = cache->subdiv_loop_subdiv_edge_index;
558 ctx->subdiv_loop_face_index = cache->subdiv_loop_face_index;
560 ctx->orig_index_vert =
static_cast<const int *
>(
563 ctx->orig_index_edge =
static_cast<const int *
>(
566 if (cache->num_subdiv_verts) {
568 "subdiv_vert_origindex_map");
569 for (
int i = 0;
i < num_verts;
i++) {
570 ctx->vert_origindex_map[
i] = -1;
574 if (cache->num_subdiv_edges) {
576 "subdiv_edge_origindex_map");
577 for (
int i = 0;
i < num_edges;
i++) {
578 ctx->edge_origindex_map[
i] = -1;
581 "subdiv_edge_draw_flag_map");
587static void draw_subdiv_vertex_corner_cb(
const bke::subdiv::ForeachContext *foreach_context,
592 const int coarse_vertex_index,
595 const int subdiv_vertex_index)
598 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
599 ctx->vert_origindex_map[subdiv_vertex_index] = coarse_vertex_index;
602static void draw_subdiv_vertex_edge_cb(
const bke::subdiv::ForeachContext * ,
615static void draw_subdiv_edge_cb(
const bke::subdiv::ForeachContext *foreach_context,
617 const int coarse_edge_index,
618 const int subdiv_edge_index,
623 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
625 if (!ctx->edge_origindex_map) {
632 if (!ctx->cache->optimal_display) {
633 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
637 if (ctx->orig_index_edge) {
638 const int origindex = ctx->orig_index_edge[coarse_edge_index];
639 ctx->edge_origindex_map[subdiv_edge_index] = origindex;
640 if (!(origindex ==
ORIGINDEX_NONE && ctx->cache->hide_unmapped_edges)) {
642 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
646 ctx->edge_origindex_map[subdiv_edge_index] = coarse_edge_index;
647 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
652static void draw_subdiv_loop_cb(
const bke::subdiv::ForeachContext *foreach_context,
654 const int ptex_face_index,
658 const int coarse_face_index,
660 const int subdiv_loop_index,
661 const int subdiv_vertex_index,
662 const int subdiv_edge_index)
664 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
665 ctx->patch_coords[subdiv_loop_index] = make_patch_coord(ptex_face_index, u,
v);
667 int coarse_vertex_index = ctx->vert_origindex_map[subdiv_vertex_index];
669 ctx->subdiv_loop_subdiv_vert_index[subdiv_loop_index] = subdiv_vertex_index;
670 ctx->subdiv_loop_subdiv_edge_index[subdiv_loop_index] = subdiv_edge_index;
671 ctx->subdiv_loop_face_index[subdiv_loop_index] = coarse_face_index;
672 ctx->subdiv_loop_vert_index[subdiv_loop_index] = coarse_vertex_index;
675static void draw_subdiv_foreach_callbacks(bke::subdiv::ForeachContext *foreach_context)
677 memset(foreach_context, 0,
sizeof(*foreach_context));
678 foreach_context->topology_info = draw_subdiv_topology_info_cb;
679 foreach_context->loop = draw_subdiv_loop_cb;
680 foreach_context->edge = draw_subdiv_edge_cb;
681 foreach_context->vertex_corner = draw_subdiv_vertex_corner_cb;
682 foreach_context->vertex_edge = draw_subdiv_vertex_edge_cb;
685static void do_subdiv_traversal(DRWCacheBuildingContext *cache_building_context,
686 bke::subdiv::Subdiv *subdiv)
688 bke::subdiv::ForeachContext foreach_context;
689 draw_subdiv_foreach_callbacks(&foreach_context);
690 foreach_context.user_data = cache_building_context;
694 cache_building_context->settings,
695 cache_building_context->coarse_mesh);
700 for (
int i = 0;
i < cache_building_context->cache->num_subdiv_loops;
i++) {
701 const int edge_index = cache_building_context->subdiv_loop_subdiv_edge_index[
i];
702 cache_building_context->subdiv_loop_edge_index[
i] =
703 cache_building_context->edge_origindex_map[edge_index];
704 cache_building_context->subdiv_loop_edge_draw_flag[
i] =
705 cache_building_context->edge_draw_flag_map[edge_index];
709static gpu::VertBuf *gpu_vertbuf_create_from_format(
const GPUVertFormat &
format,
uint len)
719static void build_vertex_face_adjacency_maps(
DRWSubdivCache &cache)
723 cache.subdiv_vertex_face_adjacency_offsets = gpu_vertbuf_create_from_format(
726 MutableSpan<int> vertex_offsets = cache.subdiv_vertex_face_adjacency_offsets->data<
int>();
727 vertex_offsets.
fill(0);
730 {cache.subdiv_loop_subdiv_vert_index, cache.num_subdiv_loops}, vertex_offsets);
733 cache.num_subdiv_loops);
734 MutableSpan<int> adjacent_faces = cache.subdiv_vertex_face_adjacency->data<
int>();
737 for (
int i = 0;
i < cache.num_subdiv_loops / 4;
i++) {
738 for (
int j = 0; j < 4; j++) {
739 const int subdiv_vertex = cache.subdiv_loop_subdiv_vert_index[
i * 4 + j];
740 int first_face_offset = vertex_offsets[subdiv_vertex] + tmp_set_faces[subdiv_vertex];
741 adjacent_faces[first_face_offset] =
i;
742 tmp_set_faces[subdiv_vertex] += 1;
750 bke::subdiv::Subdiv *subdiv,
751 const Mesh *mesh_eval,
752 const SubsurfRuntimeData *runtime_data)
754 bke::subdiv::ToMeshSettings to_mesh_settings;
755 to_mesh_settings.resolution = runtime_data->
resolution;
756 to_mesh_settings.use_optimal_display =
false;
758 if (cache.resolution != to_mesh_settings.resolution) {
768 if (cache.patch_coords !=
nullptr) {
772 DRWCacheBuildingContext cache_building_context;
773 memset(&cache_building_context, 0,
sizeof(DRWCacheBuildingContext));
774 cache_building_context.coarse_mesh = mesh_eval;
775 cache_building_context.settings = &to_mesh_settings;
776 cache_building_context.cache = &cache;
778 do_subdiv_traversal(&cache_building_context, subdiv);
779 if (cache.num_subdiv_loops == 0 && cache.num_subdiv_verts == 0 && !cache.may_have_loose_geom) {
788 const OffsetIndices
faces = mesh_eval->faces();
789 if (cache.num_subdiv_loops != 0) {
791 draw_patch_map_build(&cache.gpu_patch_map, subdiv);
796 cache.fdots_patch_coords = gpu_vertbuf_create_from_format(get_blender_patch_coords_format(),
798 CompressedPatchCoord *blender_fdots_patch_coords =
799 cache.fdots_patch_coords->data<CompressedPatchCoord>().
data();
801 const int ptex_face_index = cache.face_ptex_offset[
i];
804 blender_fdots_patch_coords[
i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f);
810 blender_fdots_patch_coords[
i] = make_patch_coord(ptex_face_index, 1.0f, 1.0f);
820 build_vertex_face_adjacency_maps(cache);
823 cache.resolution = to_mesh_settings.resolution;
824 cache.num_coarse_faces =
faces.size();
829 Vector<int> first_loop_index(cache.num_subdiv_verts, -1);
833 if (cache.num_subdiv_loops > 0) {
834 memcpy(cache.corner_patch_coords->data<CompressedPatchCoord>().data(),
835 cache_building_context.patch_coords,
836 sizeof(CompressedPatchCoord) * cache.num_subdiv_loops);
838 for (
int i = 0;
i < cache.num_subdiv_loops;
i++) {
839 const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[
i];
840 if (first_loop_index[vertex] != -1) {
843 first_loop_index[vertex] =
i;
846 for (
int i = 0;
i < cache.num_subdiv_loops;
i++) {
847 const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[
i];
848 cache_building_context.patch_coords[
i] =
849 cache_building_context.patch_coords[first_loop_index[vertex]];
873 const int src_offset,
874 const int dst_offset,
875 const uint total_dispatch_size,
876 const bool has_sculpt_mask,
877 const uint edge_loose_offset)
900 const int src_offset,
901 const int dst_offset,
902 const uint total_dispatch_size,
903 const bool has_sculpt_mask =
false,
904 const uint edge_loose_offset = 0)
928#define SUBDIV_LOCAL_WORK_GROUP_SIZE 64
941 const int src_offset,
942 const int dst_offset,
943 uint total_dispatch_size,
944 const bool has_sculpt_mask =
false,
945 const uint edge_loose_offset = 0)
950 uint dispatch_rx = dispatch_size;
951 uint dispatch_ry = 1u;
952 if (dispatch_rx > max_res_x) {
960 dispatch_rx = dispatch_ry =
ceilf(
sqrtf(dispatch_size));
962 if ((dispatch_rx * (dispatch_ry - 1)) >= dispatch_size) {
973 cache, src_offset, dst_offset, total_dispatch_size, has_sculpt_mask, edge_loose_offset);
983#ifdef WITH_OPENSUBDIV
1045 const int face_varying_channel,
1046 const int dst_offset)
1048#ifdef WITH_OPENSUBDIV
1058 face_varying_channel);
1060 face_varying_channel);
1063 face_varying_channel);
1065 face_varying_channel);
1067 face_varying_channel);
1100 UNUSED_VARS(cache, uvs, face_varying_channel, dst_offset);
1221 int binding_point = 0;
1241 const int material_count)
1248 const bool do_single_material = material_count <= 1;
1258 if (!do_single_material) {
1279#ifdef WITH_OPENSUBDIV
1329 UNUSED_VARS(cache, fdots_pos, fdots_nor, fdots_indices);
1355 uint edge_loose_offset,
1356 uint num_loose_edges)
1510 const Mesh *mesh_eval,
1521 cache.
mat_end[0] = number_of_quads;
1535 const int next_offset = (
i == mesh_eval->
faces_num - 1) ? number_of_quads :
1536 subdiv_face_offset[
i + 1];
1537 const int quad_count = next_offset - subdiv_face_offset[
i];
1538 const uint mat_index =
uint(material_indices[
i]) < mat_len ?
uint(material_indices[
i]) : 0;
1539 mat_start[mat_index] += quad_count;
1543 int ofs = mat_start[0];
1545 for (
uint i = 1;
i < mat_len;
i++) {
1546 int tmp = mat_start[
i];
1552 int *mat_end =
static_cast<int *
>(
MEM_dupallocN(mat_start));
1556 const uint mat_index =
uint(material_indices[
i]) < mat_len ?
uint(material_indices[
i]) : 0;
1557 const int single_material_index = subdiv_face_offset[
i];
1558 const int material_offset = mat_end[mat_index];
1559 const int next_offset = (
i == mesh_eval->
faces_num - 1) ? number_of_quads :
1560 subdiv_face_offset[
i + 1];
1561 const int quad_count = next_offset - subdiv_face_offset[
i];
1562 mat_end[mat_index] += quad_count;
1564 per_face_mat_offset[
i] = material_offset - single_material_index;
1591 const bool is_editmode,
1592 const bool is_paint_mode,
1593 const bool do_final,
1594 const bool do_uvedit,
1597 const bool use_hide)
1606 const Mesh *mesh_eval = &mesh;
1608 if (mesh.
runtime->edit_mesh) {
1613#ifdef WITH_OPENSUBDIV
1614 draw_subdiv_invalidate_evaluator_for_orco(runtime_data->
subdiv_gpu, mesh_eval);
1618 runtime_data, mesh_eval,
true);
1631 bool evaluator_might_be_assigned = subdiv->
evaluator ==
nullptr;
1632 auto maybe_increment_cache_ref = [evaluator_might_be_assigned](
bke::subdiv::Subdiv *subdiv) {
1633 if (evaluator_might_be_assigned && subdiv->
evaluator !=
nullptr) {
1649 maybe_increment_cache_ref(subdiv);
1660 draw_cache.
mesh = mesh_eval;
1661 draw_cache.
subdiv = subdiv;
1663#ifdef WITH_OPENSUBDIV
1664 if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, runtime_data)) {
1665 maybe_increment_cache_ref(subdiv);
1679 mesh_eval->
attributes().contains(
"custom_normal");
1686 ob, mesh, is_editmode, is_paint_mode, do_final, do_uvedit, use_hide, ts);
1697 batch_cache, mbc, ibo_requests, vbo_requests, draw_cache, mr);
1699 maybe_increment_cache_ref(subdiv);
1715 const Mesh *coarse_mesh = subdiv_cache.
mesh;
1717 const int resolution = subdiv_cache.
resolution;
1718 const int resolution_1 = resolution - 1;
1719 const float inv_resolution_1 = 1.0f / float(resolution_1);
1721 const Span<float3> coarse_positions = coarse_mesh->vert_positions();
1722 const Span<int2> coarse_edges = coarse_mesh->edges();
1727 coarse_edges, coarse_mesh->
verts_num, vert_to_edge_offsets, vert_to_edge_indices);
1734 for (const int i : range) {
1735 const int coarse_edge = loose_edges[i];
1736 MutableSpan positions = edge_positions.slice(i * resolution, resolution);
1737 for (const int j : positions.index_range()) {
1738 positions[j] = bke::subdiv::mesh_interpolate_position_on_edge(coarse_positions,
1743 j * inv_resolution_1);
1765 const bool is_editmode,
1766 const bool is_paint_mode,
1767 const bool do_final,
1768 const bool do_uvedit,
1771 const bool use_hide)
1800 fprintf(stderr,
"Time to update subdivision: %f\n", end_time - begin_time);
1801 fprintf(stderr,
"Maximum FPS: %f\n", 1.0 / (end_time - begin_time));
1826#ifdef WITH_OPENSUBDIV
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
#define MAX_GPU_SUBDIV_SSBOS
blender::bke::subdiv::Subdiv * BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtime_data, const Mesh *mesh, bool for_draw_code)
void void void * BLI_linklist_pop(LinkNode **listp) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
MINLINE uint divide_ceil_u(uint a, uint b)
double BLI_time_now_seconds(void)
Object is a sort of wrapper for general info.
int GPU_max_work_group_count(int index)
void GPU_compute_dispatch(GPUShader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_indexbuf_bind_as_ssbo(blender::gpu::IndexBuf *elem, int binding)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_ELEMENT_ARRAY
@ GPU_BARRIER_VERTEX_ATTRIB_ARRAY
void GPU_storagebuf_bind(GPUStorageBuf *ssbo, int slot)
void GPU_storagebuf_free(GPUStorageBuf *ssbo)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
#define GPU_vertbuf_init_with_format(verts, format)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
blender::gpu::VertBuf * GPU_vertbuf_calloc()
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_init_with_format_ex(blender::gpu::VertBuf &verts, const GPUVertFormat &format, GPUUsageType)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr void fill(const T &value) const
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool contains(const T &value) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
gpu::VertBuf * get_face_varying_source_buf(const int face_varying_channel)
GPUStorageBuf * get_patch_index_buf()
GPUStorageBuf * create_face_varying_patch_array_buf(const int face_varying_channel)
GPUStorageBuf * create_patch_arrays_buf()
GPUStorageBuf * get_face_varying_patch_param_buf(const int face_varying_channel)
GPUStorageBuf * get_face_varying_patch_index_buf(const int face_varying_channel)
GPUStorageBuf * get_patch_param_buf()
int get_face_varying_source_offset(const int face_varying_channel) const
gpu::VertBuf * get_source_data_buf()
gpu::VertBuf * get_source_buf()
bool hasVertexData() const
void getPatchMap(blender::gpu::VertBuf *patch_map_handles, blender::gpu::VertBuf *patch_map_quadtree, int *min_patch_face, int *max_patch_face, int *max_depth, int *patches_are_triangular)
#define SUBDIV_COARSE_FACE_FLAG_HIDDEN
#define SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK
#define SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK
#define SUBDIV_COARSE_FACE_FLAG_OFFSET
#define SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK
#define SUBDIV_COARSE_FACE_FLAG_SMOOTH
#define SUBDIV_COARSE_FACE_FLAG_ACTIVE
#define SUBDIV_COARSE_FACE_FLAG_SELECT_MASK
#define SUBDIV_LOCAL_WORK_GROUP_SIZE
#define SUBDIV_COARSE_FACE_FLAG_SELECT
#define SUBDIV_COARSE_FACE_LOOP_START_MASK
GPUShader * DRW_shader_subdiv_custom_data_get(GPUVertCompType comp_type, int dimensions)
GPUShader * DRW_shader_subdiv_get(SubdivShaderType shader_type)
@ PATCH_EVALUATION_FACE_DOTS
@ BUFFER_NORMALS_FINALIZE
@ BUFFER_UV_STRETCH_ANGLE
@ BUFFER_CUSTOM_NORMALS_FINALIZE
@ BUFFER_NORMALS_ACCUMULATE
@ PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS
@ BUFFER_TRIS_MULTIPLE_MATERIALS
#define LOOP_NORMALS_INPUT_VERT_ORIG_INDEX_BUF_SLOT
#define EDGE_FAC_EDGE_FAC_BUF_SLOT
#define LINES_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define TRIS_OUTPUT_TRIS_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_NORMALS_BUF_SLOT
#define LOOP_NORMALS_POS_NOR_BUF_SLOT
#define PATCH_EVALUATION_PATCH_ARRAY_BUFFER_BUF_SLOT
#define CUSTOM_DATA_SOURCE_DATA_BUF_SLOT
#define CUSTOM_DATA_FACE_PTEX_OFFSET_BUF_SLOT
#define LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT
#define LINES_OUTPUT_LINES_BUF_SLOT
#define PATCH_EVALUATION_INPUT_VERTEX_ORIG_INDEX_BUF_SLOT
#define NORMALS_ACCUMULATE_POS_NOR_BUF_SLOT
#define NORMALS_FINALIZE_VERTEX_LOOP_MAP_BUF_SLOT
#define SCULPT_DATA_SCULPT_DATA_BUF_SLOT
#define SHADER_DATA_BUF_SLOT
#define PATCH_EVALUATION_QUAD_NODES_BUF_SLOT
#define PATCH_EVALUATION_INPUT_PATCH_HANDLES_BUF_SLOT
#define PATCH_EVALUATION_SOURCE_EXTRA_VERTEX_BUFFER_BUF_SLOT
#define STRETCH_ANGLE_UV_STRETCHES_BUF_SLOT
#define NORMALS_ACCUMULATE_FACE_ADJACENCY_LISTS_BUF_SLOT
#define PATCH_EVALUATION_PATCH_PARAM_BUFFER_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_FDOTS_VERTEX_BUFFER_BUF_SLOT
#define LINES_LINES_LOOSE_FLAGS
#define EDGE_FAC_POLY_OTHER_MAP_BUF_SLOT
#define LINES_INPUT_EDGE_DRAW_FLAG_BUF_SLOT
#define TRIS_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define PATCH_EVALUATION_PATCH_COORDS_BUF_SLOT
#define PATCH_EVALUATION_PATCH_INDEX_BUFFER_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_INDICES_BUF_SLOT
#define NORMALS_ACCUMULATE_NORMALS_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_ORCOS_BUF_SLOT
#define SCULPT_DATA_SCULPT_FACE_SET_COLOR_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_VERTS_BUF_SLOT
#define EDGE_FAC_POS_NOR_BUF_SLOT
#define LOOP_NORMALS_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define SCULPT_DATA_SCULPT_MASK_BUF_SLOT
#define EDGE_FAC_EDGE_DRAW_FLAG_BUF_SLOT
#define PATCH_EVALUATION_SOURCE_VERTEX_BUFFER_BUF_SLOT
#define TRIS_FACE_MAT_OFFSET
#define STRETCH_AREA_COARSE_STRETCH_AREA_BUF_SLOT
#define NORMALS_FINALIZE_POS_NOR_BUF_SLOT
#define PATCH_EVALUATION_FLAGS_BUFFER_BUF_SLOT
#define CUSTOM_DATA_DESTINATION_DATA_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_FVAR_BUF_SLOT
#define SUBDIV_FACE_OFFSET_BUF_SLOT
#define CUSTOM_DATA_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define NORMALS_ACCUMULATE_VERTEX_LOOP_MAP_BUF_SLOT
#define STRETCH_AREA_SUBDIV_STRETCH_AREA_BUF_SLOT
#define PATCH_EVALUATION_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define NORMALS_ACCUMULATE_FACE_ADJACENCY_OFFSETS_BUF_SLOT
#define NORMALS_FINALIZE_VERTEX_NORMALS_BUF_SLOT
#define STRETCH_ANGLE_POS_NOR_BUF_SLOT
#define STRETCH_ANGLE_UVS_BUF_SLOT
#define CUSTOM_DATA_PATCH_COORDS_BUF_SLOT
void openSubdiv_deleteEvaluatorCache(OpenSubdiv_EvaluatorCache *evaluator_cache)
OpenSubdiv_EvaluatorCache * openSubdiv_createEvaluatorCache(eOpenSubdivEvaluator evaluator_type)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
void free(Subdiv *subdiv)
bool foreach_subdiv_geometry(Subdiv *subdiv, const ForeachContext *context, const ToMeshSettings *mesh_settings, const Mesh *coarse_mesh)
bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, Span< float3 > coarse_vert_positions, eSubdivEvaluatorType evaluator_type, OpenSubdiv_EvaluatorCache *evaluator_cache)
@ SUBDIV_EVALUATOR_TYPE_GPU
int * face_ptex_offset_get(Subdiv *subdiv)
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData &mr, int idx)
static void draw_subdiv_init_ubo_storage(const DRWSubdivCache &cache, DRWSubdivUboStorage *ubo, const int src_offset, const int dst_offset, const uint total_dispatch_size, const bool has_sculpt_mask, const uint edge_loose_offset)
static void draw_subdiv_cache_free_material_data(DRWSubdivCache &cache)
static void draw_subdiv_free_edit_mode_cache(DRWSubdivCache &cache)
void draw_subdiv_build_edge_fac_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos_nor, gpu::VertBuf *edge_draw_flag, gpu::VertBuf *poly_other_map, gpu::VertBuf *edge_fac)
static bool draw_subdiv_cache_need_face_data(const DRWSubdivCache &cache)
void draw_subdiv_extract_uvs(const DRWSubdivCache &cache, gpu::VertBuf *uvs, const int face_varying_channel, const int dst_offset)
gpu::VertBufPtr draw_subdiv_init_origindex_buffer(int32_t *vert_origindex, uint num_loops, uint loose_len)
void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache &cache, gpu::VertBuf *coarse_data, gpu::VertBuf *subdiv_data)
static void draw_patch_map_free(DRWPatchMap *gpu_patch_map)
static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache, const Mesh *mesh_eval, uint mat_len)
void draw_subdiv_build_fdots_buffers(const DRWSubdivCache &cache, gpu::VertBuf *fdots_pos, gpu::VertBuf *fdots_nor, gpu::IndexBuf *fdots_indices)
void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCache &cache)
void draw_subdiv_interp_custom_data(const DRWSubdivCache &cache, gpu::VertBuf &src_data, gpu::VertBuf &dst_data, GPUVertCompType comp_type, int dimensions, int dst_offset)
static blender::Mutex gpu_subdiv_queue_mutex
void draw_subdiv_cache_free(DRWSubdivCache &cache)
void draw_subdiv_build_tris_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *subdiv_tris, const int material_count)
static LinkNode * gpu_subdiv_free_queue
void DRW_subdiv_cache_free(bke::subdiv::Subdiv *subdiv)
void draw_subdiv_accumulate_normals(const DRWSubdivCache &cache, gpu::VertBuf *pos_nor, gpu::VertBuf *face_adjacency_offsets, gpu::VertBuf *face_adjacency_lists, gpu::VertBuf *vertex_loop_map, gpu::VertBuf *vert_normals)
void draw_subdiv_build_lines_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *lines_indices)
static uint get_dispatch_size(uint elements)
void draw_subdiv_build_lnor_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos_nor, gpu::VertBuf *lnor)
void draw_subdiv_extract_pos_nor(const DRWSubdivCache &cache, gpu::VertBuf *flags_buffer, gpu::VertBuf *pos_nor, gpu::VertBuf *orco)
static bool draw_subdiv_create_requested_buffers(Object &ob, Mesh &mesh, MeshBatchCache &batch_cache, MeshBufferCache &mbc, const Span< IBOType > ibo_requests, const Span< VBOType > vbo_requests, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool do_cage, const ToolSettings *ts, const bool use_hide)
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, DRWSubdivCache &subdiv_cache, MeshRenderData &mr)
static void drw_subdiv_compute_dispatch(const DRWSubdivCache &cache, GPUShader *shader, const int src_offset, const int dst_offset, uint total_dispatch_size, const bool has_sculpt_mask=false, const uint edge_loose_offset=0)
static DRWSubdivCache & mesh_batch_cache_ensure_subdiv_cache(MeshBatchCache &mbc)
void draw_subdiv_build_lines_loose_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *lines_indices, gpu::VertBuf *lines_flags, uint edge_loose_offset, uint num_loose_edges)
static uint32_t compute_coarse_face_flag_bm(BMFace *f, BMFace *efa_act)
static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &mr, const Mesh *mesh, MutableSpan< uint32_t > flags_data)
static void draw_subdiv_ubo_update_and_bind(const DRWSubdivCache &cache, const int src_offset, const int dst_offset, const uint total_dispatch_size, const bool has_sculpt_mask=false, const uint edge_loose_offset=0)
static uint tris_count_from_number_of_loops(const uint number_of_loops)
void draw_subdiv_build_sculpt_data_buffer(const DRWSubdivCache &cache, gpu::VertBuf *mask_vbo, gpu::VertBuf *face_set_vbo, gpu::VertBuf *sculpt_data)
void DRW_create_subdivision(Object &ob, Mesh &mesh, MeshBatchCache &batch_cache, MeshBufferCache &mbc, const Span< IBOType > ibo_requests, const Span< VBOType > vbo_requests, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool do_cage, const ToolSettings *ts, const bool use_hide)
void draw_subdiv_finalize_normals(const DRWSubdivCache &cache, gpu::VertBuf *vert_normals, gpu::VertBuf *subdiv_loop_subdiv_vert_index, gpu::VertBuf *pos_nor)
void DRW_cache_free_old_subdiv()
gpu::VertBuf * draw_subdiv_build_origindex_buffer(int *vert_origindex, uint num_loops)
static void draw_subdiv_cache_extra_coarse_face_data_mapped(const Mesh *mesh, BMesh *bm, MeshRenderData &mr, MutableSpan< uint32_t > flags_data)
static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache &cache, const Mesh *mesh, MeshRenderData &mr)
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)
static const GPUVertFormat & get_origindex_format()
static Mutex g_subdiv_eval_mutex
const GPUVertFormat & draw_subdiv_get_pos_nor_format()
void draw_subdiv_finalize_custom_normals(const DRWSubdivCache &cache, gpu::VertBuf *src_custom_normals, gpu::VertBuf *pos_nor)
void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos_nor, gpu::VertBuf *uvs, int uvs_offset, gpu::VertBuf *stretch_angles)
static OpenSubdiv_EvaluatorCache * g_subdiv_evaluator_cache
static uint64_t g_subdiv_evaluator_users
static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm, BMFace *efa_act, MutableSpan< uint32_t > flags_data)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
@ OPENSUBDIV_EVALUATOR_GPU
@ OPENSUBDIV_EVALUATOR_CPU
uint coarse_face_active_mask
uint coarse_face_loopstart_mask
bool32_t patches_are_triangular
uint coarse_face_select_mask
uint coarse_face_smooth_mask
uint coarse_face_hidden_mask
MeshRuntimeHandle * runtime
blender::opensubdiv::EvalOutputAPI * eval_output
eOpenSubdivEvaluator type
blender::bke::subdiv::Settings settings
blender::bke::subdiv::Subdiv * subdiv_gpu
OpenSubdiv_Evaluator * evaluator
blender::opensubdiv::TopologyRefinerImpl * topology_refiner
gpu::VertBuf * patch_map_quadtree
bool patches_are_triangular
gpu::VertBuf * patch_map_handles
gpu::VertBuf * face_mat_offset
DRWPatchMap gpu_patch_map
int * subdiv_loop_subdiv_vert_index
gpu::VertBuf * verts_orig_index
gpu::VertBuf * subdiv_vertex_face_adjacency_offsets
gpu::VertBuf * edges_orig_index
gpu::VertBuf * subdiv_vertex_face_adjacency
bool use_custom_loop_normals
gpu::VertBuf * fdots_patch_coords
gpu::VertBuf * extra_coarse_face_data
gpu::VertBuf * face_ptex_offset_buffer
int * subdiv_loop_face_index
gpu::VertBuf * subdiv_face_offset_buffer
int * subdiv_loop_subdiv_edge_index
gpu::VertBuf * edges_draw_flag
Array< float3 > loose_edge_positions
uint num_subdiv_triangles
gpu::VertBuf * corner_patch_coords
bke::subdiv::Subdiv * subdiv
gpu::VertBuf * patch_coords
DRWSubdivCache * subdiv_cache
MeshExtractLooseGeom loose_geom
MeshExtractType extract_type
const int * orig_index_face
VArraySpan< bool > sharp_faces
VArraySpan< bool > select_poly
VArraySpan< bool > hide_poly
bke::MeshNormalDomain normals_domain