79 #define BUFFER_INDEX(buff_name) ((offsetof(MeshBufferList, buff_name) - offsetof(MeshBufferList, vbo)) / sizeof(void *))
80 #define BUFFER_LEN (sizeof(MeshBufferList) / sizeof(void *))
82 #define _BATCH_MAP1(a) batches_that_use_buffer(BUFFER_INDEX(a))
83 #define _BATCH_MAP2(a, b) _BATCH_MAP1(a) | _BATCH_MAP1(b)
84 #define _BATCH_MAP3(a, b, c) _BATCH_MAP2(a, b) | _BATCH_MAP1(c)
85 #define _BATCH_MAP4(a, b, c, d) _BATCH_MAP3(a, b, c) | _BATCH_MAP1(d)
86 #define _BATCH_MAP5(a, b, c, d, e) _BATCH_MAP4(a, b, c, d) | _BATCH_MAP1(e)
87 #define _BATCH_MAP6(a, b, c, d, e, f) _BATCH_MAP5(a, b, c, d, e) | _BATCH_MAP1(f)
88 #define _BATCH_MAP7(a, b, c, d, e, f, g) _BATCH_MAP6(a, b, c, d, e, f) | _BATCH_MAP1(g)
89 #define _BATCH_MAP8(a, b, c, d, e, f, g, h) _BATCH_MAP7(a, b, c, d, e, f, g) | _BATCH_MAP1(h)
90 #define _BATCH_MAP9(a, b, c, d, e, f, g, h, i) _BATCH_MAP8(a, b, c, d, e, f, g, h) | _BATCH_MAP1(i)
91 #define _BATCH_MAP10(a, b, c, d, e, f, g, h, i, j) _BATCH_MAP9(a, b, c, d, e, f, g, h, i) | _BATCH_MAP1(j)
93 #define BATCH_MAP(...) VA_NARGS_CALL_OVERLOAD(_BATCH_MAP, __VA_ARGS__)
97 #define TRIS_PER_MAT_INDEX BUFFER_LEN
101 switch (buffer_index) {
205 if (batch_map & batch_requested) {
252 cd_used->
uv |= (1 << layer);
264 cd_used->
uv |= (1 << layer);
271 int gpumat_array_len,
282 Mesh me_query = blender::dna::shallow_zero_initialize();
285 ID_ME, cd_vdata, cd_edata, cd_ldata, cd_pdata,
nullptr, &me_query.
id);
292 const StringRefNull default_color_name = default_color ? default_color->
name :
"";
294 for (
int i = 0; i < gpumat_array_len; i++) {
299 const char *name = gpu_attr->name;
302 std::optional<eAttrDomain> domain;
304 if (gpu_attr->is_default_color) {
305 name = default_color_name.
c_str();
313 if (name[0] !=
'\0') {
360 cd_used.
uv |= (1 << layer);
370 if (layer == -1 && name[0] !=
'\0') {
375 cd_used.
tan |= (1 << layer);
397 if (layer != -1 && domain.has_value()) {
424 memset(wstate, 0,
sizeof(*wstate));
437 memcpy(wstate_dst, wstate_src,
sizeof(*wstate_dst));
453 return ((!array1 && !array2) ||
454 (array1 && array2 && memcmp(array1, array2,
size *
sizeof(
bool)) == 0));
461 return a->defgroup_active ==
b->defgroup_active &&
a->defgroup_len ==
b->defgroup_len &&
462 a->flags ==
b->flags &&
a->alert_mode ==
b->alert_mode &&
463 a->defgroup_sel_count ==
b->defgroup_sel_count &&
476 memset(wstate, 0,
sizeof(*wstate));
553 if (cache ==
nullptr) {
592 memset(cache, 0,
sizeof(*cache));
653 for (
int i = 0; i < cache->
mat_len; i++) {
664 for (
int i = 0; i < cache->
mat_len; i++) {
697 vbo.edituv_stretch_area,
701 vbo.fdots_edituv_data,
729 vbo.fdots_edituv_data,
740 if (cache ==
nullptr) {
750 batch_map =
BATCH_MAP(vbo.edit_data, vbo.fdots_nor);
764 batch_map =
BATCH_MAP(ibo.lines_paint_mask, vbo.pos_nor, vbo.lnor);
782 batch_map =
BATCH_MAP(vbo.edituv_data, vbo.fdots_edituv_data);
794 for (
int i = 0; i <
sizeof(mbuflist->
vbo) /
sizeof(
void *); i++) {
797 for (
int i = 0; i <
sizeof(mbuflist->
ibo) /
sizeof(
void *); i++) {
835 for (
int i = 0; i < cache->
mat_len; i++) {
840 for (
int i = 0; i <
sizeof(cache->
batch) /
sizeof(
void *); i++) {
875 "No uv layer available in texpaint, but batches requested anyway!");
890 Mesh me_query = blender::dna::shallow_zero_initialize();
892 ID_ME, cd_vdata,
nullptr, cd_ldata,
nullptr,
nullptr, &me_query.
id);
894 auto request_color_attribute = [&](
const char *name) {
906 request_color_attribute(
active->name);
909 request_color_attribute(render->name);
982 uint gpumat_array_len)
988 object, me, gpumat_array, gpumat_array_len, &attrs_needed);
1178 "No uv layer available in edituv, but batches requested anyway!");
1187 float **tot_uv_area)
1193 if (tot_area !=
nullptr) {
1196 if (tot_uv_area !=
nullptr) {
1268 if (cache ==
nullptr) {
1280 if (ctime - cache->
lastmatch >
U.vbotimeout) {
1299 static void drw_mesh_batch_cache_check_available(
struct TaskGraph *task_graph,
Mesh *me)
1335 const bool is_paint_mode,
1336 const bool use_hide)
1344 bool cd_uv_update =
false;
1349 drw_mesh_batch_cache_check_available(task_graph, me);
1359 for (
const int buffer_index : used_buffer_indices) {
1378 const bool is_editmode = (me->
edit_mesh !=
nullptr) &&
1400 if (batch_requested &
1421 if (cd_overlap ==
false || attr_overlap ==
false) {
1425 cd_uv_update =
true;
1445 for (
int i = 0; i < cache->
mat_len; i++) {
1464 if (cd_uv_update || (cache->
is_uvsyncsel != is_uvsyncsel)) {
1489 if ((batch_requested & ~cache->
batch_ready) == 0) {
1491 drw_mesh_batch_cache_check_available(task_graph, me);
1502 if (do_update_sculpt_normals) {
1509 bool do_cage =
false, do_uvcage =
false;
1510 if (is_editmode && is_mode_active) {
1514 do_cage = editmesh_eval_final != editmesh_eval_cage;
1636 for (
int i = 0; i < cache->
mat_len; i++) {
1806 auto assert_final_deps_valid = [&](
const int buffer_index) {
1808 batches_that_use_buffer_local.
lookup(buffer_index));
1813 assert_final_deps_valid(
BUFFER_INDEX(vbo.sculpt_data));
1816 assert_final_deps_valid(
BUFFER_INDEX(vbo.mesh_analysis));
1827 assert_final_deps_valid(
BUFFER_INDEX(vbo.edituv_data));
1828 assert_final_deps_valid(
BUFFER_INDEX(vbo.edituv_stretch_area));
1829 assert_final_deps_valid(
BUFFER_INDEX(vbo.edituv_stretch_angle));
1831 assert_final_deps_valid(
BUFFER_INDEX(vbo.fdots_edituv_data));
1838 assert_final_deps_valid(
BUFFER_INDEX(ibo.lines_loose));
1839 assert_final_deps_valid(
BUFFER_INDEX(ibo.lines_adjacency));
1840 assert_final_deps_valid(
BUFFER_INDEX(ibo.lines_paint_mask));
1843 assert_final_deps_valid(
BUFFER_INDEX(ibo.edituv_tris));
1844 assert_final_deps_valid(
BUFFER_INDEX(ibo.edituv_lines));
1845 assert_final_deps_valid(
BUFFER_INDEX(ibo.edituv_points));
1846 assert_final_deps_valid(
BUFFER_INDEX(ibo.edituv_fdots));
1885 if (do_subdivision) {
1930 drw_mesh_batch_cache_check_available(task_graph, me);
Generic geometry attributes built on CustomData.
struct CustomDataLayer * BKE_id_attributes_active_color_get(const struct ID *id)
struct CustomDataLayer * BKE_id_attributes_render_color_get(const struct ID *id)
void BKE_id_attribute_copy_domains_temp(short id_type, const struct CustomData *vdata, const struct CustomData *edata, const struct CustomData *ldata, const struct CustomData *pdata, const struct CustomData *cdata, struct ID *r_id)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_active_layer(const struct CustomData *data, int type)
int CustomData_get_stencil_layer(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
int CustomData_get_render_layer(const struct CustomData *data, int type)
@ BKE_MESH_BATCH_DIRTY_UVEDIT_ALL
@ BKE_MESH_BATCH_DIRTY_SELECT_PAINT
@ BKE_MESH_BATCH_DIRTY_SHADING
@ BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT
@ BKE_MESH_BATCH_DIRTY_ALL
@ BKE_MESH_BATCH_DIRTY_SELECT
struct Mesh * BKE_object_get_editmesh_eval_final(const struct Object *object)
struct Mesh * BKE_object_get_editmesh_eval_cage(const struct Object *object)
A BVH for high poly meshes.
bool BKE_pbvh_is_drawing(const PBVH *pbvh)
void BKE_pbvh_update_normals(PBVH *pbvh, struct SubdivCCG *subdiv_ccg)
bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh)
bool BKE_subsurf_modifier_has_gpu_subdiv(const struct Mesh *mesh)
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_task_graph_work_and_wait(struct TaskGraph *task_graph)
pthread_mutex_t ThreadMutex
#define ME_USING_MIRROR_X_VERTEX_GROUPS(_me)
Object is a sort of wrapper for general info.
#define UV_SYNC_SELECTION
#define GPU_BATCH_CLEAR_SAFE(batch)
#define GPU_BATCH_DISCARD_SAFE(batch)
struct GPUIndexBuf GPUIndexBuf
#define GPU_INDEXBUF_DISCARD_SAFE(elem)
_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
ListBase GPU_material_attributes(GPUMaterial *material)
struct GPUVertBuf GPUVertBuf
#define GPU_VERTBUF_DISCARD_SAFE(verts)
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint32_t atomic_fetch_and_or_uint32(uint32_t *p, uint32_t x)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
const Value & lookup(const Key &key) const
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
constexpr const char * c_str() const
void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, ThreadMutex *render_mutex)
bool drw_custom_data_match_attribute(const CustomData *custom_data, const char *name, int *r_layer_index, eCustomDataType *r_type)
DRW_AttributeRequest * drw_attributes_add_request(DRW_Attributes *attrs, const char *name, const eCustomDataType type, const int layer_index, const eAttrDomain domain)
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b)
void drw_attributes_clear(DRW_Attributes *attributes)
GPUVertBuf * DRW_mesh_batch_cache_pos_vertbuf_get(Mesh *me)
static void mesh_batch_cache_request_surface_batches(MeshBatchCache *cache)
GPUBatch * DRW_mesh_batch_cache_get_edit_facedots(Mesh *me)
int DRW_mesh_material_count_get(const Object *object, const Mesh *me)
BLI_INLINE void mesh_batch_cache_add_request(MeshBatchCache *cache, DRWBatchFlag new_flag)
static void mesh_batch_cache_discard_batch(MeshBatchCache *cache, const DRWBatchFlag batch_map)
GPUBatch * DRW_mesh_batch_cache_get_edituv_faces_stretch_area(Object *object, Mesh *me, float **tot_area, float **tot_uv_area)
GPUBatch * DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me)
static void request_active_and_default_color_attributes(const Object &object, const Mesh &mesh, DRW_Attributes &attributes)
static void mesh_batch_cache_discard_surface_batches(MeshBatchCache *cache)
GPUBatch * DRW_mesh_batch_cache_get_edit_vnors(Mesh *me)
void DRW_mesh_batch_cache_validate(Object *object, Mesh *me)
static void mesh_cd_calc_edit_uv_layer(const Mesh *UNUSED(me), DRW_MeshCDMask *cd_used)
GPUBatch ** DRW_mesh_batch_cache_get_surface_texpaint(Object *object, Mesh *me)
void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime)
GPUBatch * DRW_mesh_batch_cache_get_triangles_with_select_id(Mesh *me)
BLI_INLINE void mesh_cd_layers_type_merge(DRW_MeshCDMask *a, DRW_MeshCDMask b)
void DRW_mesh_batch_cache_free(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_sculpt_overlays(Mesh *me)
static bool mesh_batch_cache_valid(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edituv_facedots(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(Object *object, Mesh *me)
static MeshBatchCache * mesh_batch_cache_get(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_surface_texpaint_single(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me)
BLI_INLINE void mesh_cd_layers_type_clear(DRW_MeshCDMask *a)
static void mesh_batch_cache_init(Object *object, Mesh *me)
static void drw_add_attributes_vbo(GPUBatch *batch, MeshBufferList *mbuflist, DRW_Attributes *attr_used)
static void mesh_buffer_list_clear(MeshBufferList *mbuflist)
GPUBatch * DRW_mesh_batch_cache_get_edit_mesh_analysis(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edit_vertices(Mesh *me)
static void mesh_batch_cache_clear(Mesh *me)
#define BUFFER_INDEX(buff_name)
GPUBatch * DRW_mesh_batch_cache_get_surface_weights(Mesh *me)
static void texpaint_request_active_uv(MeshBatchCache *cache, Object *object, Mesh *me)
GPUBatch ** DRW_mesh_batch_cache_get_surface_shaded(Object *object, Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
static bool drw_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const struct DRW_MeshWeightState *b)
static void drw_mesh_weight_state_clear(struct DRW_MeshWeightState *wstate)
GPUBatch * DRW_mesh_batch_cache_get_edituv_edges(Object *object, Mesh *me)
static void edituv_request_active_uv(MeshBatchCache *cache, Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_surface(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me)
#define TRIS_PER_MAT_INDEX
static void mesh_batch_cache_discard_uvedit(MeshBatchCache *cache)
GPUBatch * DRW_mesh_batch_cache_get_edit_edges(Mesh *me)
static constexpr DRWBatchFlag batches_that_use_buffer(const int buffer_index)
GPUBatch * DRW_mesh_batch_cache_get_loose_edges(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
GPUBatch * DRW_mesh_batch_cache_get_uv_edges(Object *object, Mesh *me)
static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, const Mesh *me, struct GPUMaterial **gpumat_array, int gpumat_array_len, DRW_Attributes *attributes)
GPUBatch * DRW_mesh_batch_cache_get_all_edges(Mesh *me)
static void mesh_cd_calc_active_mask_uv_layer(const Object *object, const Mesh *me, DRW_MeshCDMask *cd_used)
static void mesh_batch_cache_free_subdiv_cache(MeshBatchCache *cache)
GPUBatch * DRW_mesh_batch_cache_get_edituv_verts(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edit_skin_roots(Mesh *me)
static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache, const struct DRW_MeshWeightState *wstate)
static void mesh_buffer_cache_clear(MeshBufferCache *mbc)
GPUBatch * DRW_mesh_batch_cache_get_surface_edges(Object *object, Mesh *me)
BLI_INLINE bool mesh_cd_layers_type_overlap(DRW_MeshCDMask a, DRW_MeshCDMask b)
GPUBatch * DRW_mesh_batch_cache_get_edit_triangles(Mesh *me)
static void drw_mesh_weight_state_copy(struct DRW_MeshWeightState *wstate_dst, const struct DRW_MeshWeightState *wstate_src)
void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
GPUBatch * DRW_mesh_batch_cache_get_edit_lnors(Mesh *me)
void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, Object *ob, Mesh *me, const Scene *scene, const bool is_paint_mode, const bool use_hide)
static bool drw_mesh_flags_equal(const bool *array1, const bool *array2, int size)
BLI_INLINE bool mesh_cd_layers_type_equal(DRW_MeshCDMask a, DRW_MeshCDMask b)
GPUBatch * DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_all_verts(Mesh *me)
static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache)
static void drw_mesh_weight_state_extract(Object *ob, Mesh *me, const ToolSettings *ts, bool paint_mode, struct DRW_MeshWeightState *wstate)
static void mesh_cd_calc_active_uv_layer(const Object *object, const Mesh *me, DRW_MeshCDMask *cd_used)
GPUBatch * DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_edituv_faces(Object *object, Mesh *me)
GPUBatch * DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me)
void DRW_create_subdivision(Object *ob, Mesh *mesh, MeshBatchCache *batch_cache, MeshBufferCache *mbc, const bool is_editmode, const bool is_paint_mode, const bool is_mode_active, const float obmat[4][4], const bool do_final, const bool do_uvedit, const bool do_cage, const ToolSettings *ts, const bool use_hide)
void draw_subdiv_cache_free(DRWSubdivCache *cache)
BLI_INLINE void DRW_vbo_request(GPUBatch *batch, GPUVertBuf **vbo)
BLI_INLINE bool DRW_vbo_requested(GPUVertBuf *vbo)
BLI_INLINE void DRW_ibo_request(GPUBatch *batch, GPUIndexBuf **ibo)
BLI_INLINE bool DRW_ibo_requested(GPUIndexBuf *ibo)
BLI_INLINE bool DRW_batch_requested(GPUBatch *batch, GPUPrimType prim_type)
BLI_INLINE GPUBatch * DRW_batch_request(GPUBatch **batch)
bool DRW_object_is_in_edit_mode(const Object *ob)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
bool active
all scheduled work for the GPU.
void mesh_buffer_cache_create_requested(TaskGraph *task_graph, MeshBatchCache *cache, MeshBufferCache *mbc, Object *object, Mesh *me, bool is_editmode, bool is_paint_mode, bool is_mode_active, const float obmat[4][4], bool do_final, bool do_uvedit, const Scene *scene, const ToolSettings *ts, bool use_hide)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
DRW_MeshWeightState weight_state
DRW_MeshCDMask cd_used_over_time
GPUBatch ** surface_per_mat
DRWBatchFlag batch_requested
DRWSubdivCache * subdiv_cache
DRW_Attributes attr_needed
GPUIndexBuf ** tris_per_mat
DRW_Attributes attr_used_over_time
GPUBatch * surface_weights
GPUBatch * edituv_faces_stretch_angle
GPUBatch * edit_selection_faces
GPUBatch * edituv_faces_stretch_area
GPUBatch * edge_detection
GPUBatch * edit_mesh_analysis
GPUBatch * edit_selection_fdots
GPUBatch * edit_skin_roots
GPUBatch * edit_selection_edges
GPUBatch * wire_loops_uvs
GPUBatch * sculpt_overlays
GPUBatch * edit_selection_verts
GPUBatch * edit_triangles
MeshExtractLooseGeom loose_geom
struct MeshBufferCache::@274 poly_sorted
GPUIndexBuf * lines_paint_mask
GPUVertBuf * edituv_stretch_area
GPUIndexBuf * lines_loose
GPUVertBuf * attr[GPU_MAX_ATTR]
GPUVertBuf * fdots_edituv_data
GPUIndexBuf * edituv_points
GPUIndexBuf * edituv_fdots
GPUIndexBuf * edituv_tris
GPUIndexBuf * edituv_lines
struct MeshBufferList::@272 vbo
struct MeshBufferList::@273 ibo
GPUVertBuf * edituv_stretch_angle
GPUIndexBuf * lines_adjacency
GPUVertBuf * mesh_analysis
struct SubdivCCG * subdiv_ccg
struct BMEditMesh * edit_mesh
ListBase vertex_group_names
int vertex_group_active_index
struct SculptSession * sculpt
struct ToolSettings * toolsettings