Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h9
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.cc14
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_private.h7
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh_render_data.c104
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c2
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc47
6 files changed, 136 insertions, 47 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 46234366251..2c4e4dfe76b 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -83,8 +83,9 @@ typedef enum eMRDataType {
MR_DATA_LOOPTRI = 1 << 3,
/** Force loop normals calculation. */
MR_DATA_TAN_LOOP_NOR = 1 << 4,
+ MR_DATA_MAT_OFFSETS = 1 << 5,
} eMRDataType;
-ENUM_OPERATORS(eMRDataType, MR_DATA_TAN_LOOP_NOR)
+ENUM_OPERATORS(eMRDataType, MR_DATA_MAT_OFFSETS)
#ifdef __cplusplus
extern "C" {
@@ -166,6 +167,12 @@ typedef struct MeshBufferExtractionCache {
int *verts;
int *edges;
} loose_geom;
+
+ struct {
+ int *tri;
+ int visible_tri_len;
+ } mat_offsets;
+
} MeshBufferExtractionCache;
typedef enum DRWBatchFlag {
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index c6b749fe11a..021565fceac 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -498,11 +498,15 @@ static struct TaskNode *extract_task_node_create(struct TaskGraph *task_graph,
* \{ */
struct MeshRenderDataUpdateTaskData {
MeshRenderData *mr = nullptr;
+ MeshBufferExtractionCache *cache = nullptr;
eMRIterType iter_type;
eMRDataType data_flag;
- MeshRenderDataUpdateTaskData(MeshRenderData *mr, eMRIterType iter_type, eMRDataType data_flag)
- : mr(mr), iter_type(iter_type), data_flag(data_flag)
+ MeshRenderDataUpdateTaskData(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache,
+ eMRIterType iter_type,
+ eMRDataType data_flag)
+ : mr(mr), cache(cache), iter_type(iter_type), data_flag(data_flag)
{
}
@@ -533,15 +537,17 @@ static void mesh_extract_render_data_node_exec(void *__restrict task_data)
mesh_render_data_update_normals(mr, data_flag);
mesh_render_data_update_looptris(mr, iter_type, data_flag);
+ mesh_render_data_update_mat_offsets(mr, update_task_data->cache, data_flag);
}
static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *task_graph,
MeshRenderData *mr,
+ MeshBufferExtractionCache *cache,
const eMRIterType iter_type,
const eMRDataType data_flag)
{
MeshRenderDataUpdateTaskData *task_data = new MeshRenderDataUpdateTaskData(
- mr, iter_type, data_flag);
+ mr, cache, iter_type, data_flag);
struct TaskNode *task_node = BLI_task_graph_node_create(
task_graph,
@@ -702,7 +708,7 @@ static void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
#endif
struct TaskNode *task_node_mesh_render_data = mesh_extract_render_data_node_create(
- task_graph, mr, iter_type, data_flag);
+ task_graph, mr, extraction_cache, iter_type, data_flag);
/* Simple heuristic. */
const bool use_thread = (mr->loop_len + mr->loop_loose_len) > MIM_RANGE_LEN;
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_private.h b/source/blender/draw/intern/draw_cache_extract_mesh_private.h
index 2ece0b4f1db..8c7011dd13c 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_private.h
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_private.h
@@ -94,6 +94,10 @@ typedef struct MeshRenderData {
float (*loop_normals)[3];
float (*poly_normals)[3];
int *lverts, *ledges;
+ struct {
+ int *tri;
+ int visible_tri_len;
+ } mat_offsets;
} MeshRenderData;
BLI_INLINE BMFace *bm_original_face_get(const MeshRenderData *mr, int idx)
@@ -238,6 +242,9 @@ MeshRenderData *mesh_render_data_create(Mesh *me,
const eMRIterType iter_type);
void mesh_render_data_free(MeshRenderData *mr);
void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_flag);
+void mesh_render_data_update_mat_offsets(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache,
+ const eMRDataType data_flag);
void mesh_render_data_update_looptris(MeshRenderData *mr,
const eMRIterType iter_type,
const eMRDataType data_flag);
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.c b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.c
index 3efd86affca..7e9fe9b3bdb 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.c
@@ -167,6 +167,110 @@ static void mesh_render_data_ledges_bm(const MeshRenderData *mr,
/** \} */
/* ---------------------------------------------------------------------- */
+/** \name Material Offsets
+ *
+ * Material offsets contains the offset of a material after sorting tris based on their material.
+ *
+ * \{ */
+static void mesh_render_data_mat_offset_load(MeshRenderData *mr,
+ const MeshBufferExtractionCache *cache);
+static void mesh_render_data_mat_offset_ensure(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache);
+static void mesh_render_data_mat_offset_build(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache);
+static void mesh_render_data_mat_offset_build_bm(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache);
+static void mesh_render_data_mat_offset_build_mesh(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache);
+static void mesh_render_data_mat_offset_apply_offset(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache);
+
+void mesh_render_data_update_mat_offsets(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache,
+ const eMRDataType data_flag)
+{
+ if (data_flag & MR_DATA_MAT_OFFSETS) {
+ mesh_render_data_mat_offset_ensure(mr, cache);
+ mesh_render_data_mat_offset_load(mr, cache);
+ }
+}
+
+static void mesh_render_data_mat_offset_load(MeshRenderData *mr,
+ const MeshBufferExtractionCache *cache)
+{
+ mr->mat_offsets.tri = cache->mat_offsets.tri;
+ mr->mat_offsets.visible_tri_len = cache->mat_offsets.visible_tri_len;
+}
+
+static void mesh_render_data_mat_offset_ensure(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache)
+{
+ if (cache->mat_offsets.tri) {
+ return;
+ }
+ mesh_render_data_mat_offset_build(mr, cache);
+}
+
+static void mesh_render_data_mat_offset_build(MeshRenderData *mr, MeshBufferExtractionCache *cache)
+{
+ size_t mat_tri_idx_size = sizeof(int) * mr->mat_len;
+ cache->mat_offsets.tri = MEM_callocN(mat_tri_idx_size, __func__);
+
+ /* Count how many triangles for each material. */
+ if (mr->extract_type == MR_EXTRACT_BMESH) {
+ mesh_render_data_mat_offset_build_bm(mr, cache);
+ }
+ else {
+ mesh_render_data_mat_offset_build_mesh(mr, cache);
+ }
+
+ mesh_render_data_mat_offset_apply_offset(mr, cache);
+}
+
+static void mesh_render_data_mat_offset_build_bm(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache)
+{
+ int *mat_tri_len = cache->mat_offsets.tri;
+ BMIter iter;
+ BMFace *efa;
+ BM_ITER_MESH (efa, &iter, mr->bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ int mat = min_ii(efa->mat_nr, mr->mat_len - 1);
+ mat_tri_len[mat] += efa->len - 2;
+ }
+ }
+}
+
+static void mesh_render_data_mat_offset_build_mesh(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache)
+{
+ int *mat_tri_len = cache->mat_offsets.tri;
+ const MPoly *mp = mr->mpoly;
+ for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
+ if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+ int mat = min_ii(mp->mat_nr, mr->mat_len - 1);
+ mat_tri_len[mat] += mp->totloop - 2;
+ }
+ }
+}
+
+static void mesh_render_data_mat_offset_apply_offset(MeshRenderData *mr,
+ MeshBufferExtractionCache *cache)
+{
+ int *mat_tri_len = cache->mat_offsets.tri;
+ int ofs = mat_tri_len[0];
+ mat_tri_len[0] = 0;
+ for (int i = 1; i < mr->mat_len; i++) {
+ int tmp = mat_tri_len[i];
+ mat_tri_len[i] = ofs;
+ ofs += tmp;
+ }
+ cache->mat_offsets.visible_tri_len = ofs;
+}
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
/** \name Mesh/BMesh Interface (indirect, partially cached access to complex data).
* \{ */
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 38f3f4b433a..e4c682e1765 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -725,6 +725,8 @@ static void mesh_buffer_extraction_cache_clear(MeshBufferExtractionCache *extrac
MEM_SAFE_FREE(extraction_cache->loose_geom.edges);
extraction_cache->loose_geom.edge_len = 0;
extraction_cache->loose_geom.vert_len = 0;
+
+ MEM_SAFE_FREE(extraction_cache->mat_offsets.tri);
}
static void mesh_batch_cache_clear(Mesh *me)
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index 70b46481b51..ec968fa33da 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -33,7 +33,7 @@ namespace blender::draw {
struct MeshExtract_Tri_Data {
GPUIndexBufBuilder elb;
- int *tri_mat_start;
+ const int *tri_mat_start;
int *tri_mat_end;
};
@@ -43,45 +43,9 @@ static void extract_tris_init(const MeshRenderData *mr,
void *tls_data)
{
MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(tls_data);
-
- size_t mat_tri_idx_size = sizeof(int) * mr->mat_len;
- data->tri_mat_start = static_cast<int *>(MEM_callocN(mat_tri_idx_size, __func__));
- data->tri_mat_end = static_cast<int *>(MEM_callocN(mat_tri_idx_size, __func__));
-
- int *mat_tri_len = data->tri_mat_start;
- /* Count how many triangle for each material. */
- if (mr->extract_type == MR_EXTRACT_BMESH) {
- BMIter iter;
- BMFace *efa;
- BM_ITER_MESH (efa, &iter, mr->bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
- int mat = min_ii(efa->mat_nr, mr->mat_len - 1);
- mat_tri_len[mat] += efa->len - 2;
- }
- }
- }
- else {
- const MPoly *mp = mr->mpoly;
- for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
- int mat = min_ii(mp->mat_nr, mr->mat_len - 1);
- mat_tri_len[mat] += mp->totloop - 2;
- }
- }
- }
- /* Accumulate triangle lengths per material to have correct offsets. */
- int ofs = mat_tri_len[0];
- mat_tri_len[0] = 0;
- for (int i = 1; i < mr->mat_len; i++) {
- int tmp = mat_tri_len[i];
- mat_tri_len[i] = ofs;
- ofs += tmp;
- }
-
- memcpy(data->tri_mat_end, mat_tri_len, mat_tri_idx_size);
-
- int visible_tri_tot = ofs;
- GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, visible_tri_tot, mr->loop_len);
+ data->tri_mat_start = mr->mat_offsets.tri;
+ data->tri_mat_end = static_cast<int *>(MEM_dupallocN(data->tri_mat_start));
+ GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, mr->mat_offsets.visible_tri_len, mr->loop_len);
}
static void extract_tris_iter_looptri_bm(const MeshRenderData *mr,
@@ -146,7 +110,6 @@ static void extract_tris_finish(const MeshRenderData *mr,
GPU_indexbuf_create_subrange_in_place(mbc_final->tris_per_mat[i], ibo, start, len);
}
}
- MEM_freeN(data->tri_mat_start);
MEM_freeN(data->tri_mat_end);
}
@@ -157,7 +120,7 @@ constexpr MeshExtract create_extractor_tris()
extractor.iter_looptri_bm = extract_tris_iter_looptri_bm;
extractor.iter_looptri_mesh = extract_tris_iter_looptri_mesh;
extractor.finish = extract_tris_finish;
- extractor.data_type = MR_DATA_NONE;
+ extractor.data_type = MR_DATA_MAT_OFFSETS;
extractor.data_size = sizeof(MeshExtract_Tri_Data);
extractor.use_threading = false;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.tris);