[Bf-blender-cvs] [178086d5810] master: Draw Cache: extract tris in parallel ranges

Germano Cavalcante noreply at git.blender.org
Wed Jul 21 20:15:06 CEST 2021


Commit: 178086d5810a0de9e1d95c7fbd6c443cd53af40d
Author: Germano Cavalcante
Date:   Tue Jul 20 11:43:38 2021 -0300
Branches: master
https://developer.blender.org/rB178086d5810a0de9e1d95c7fbd6c443cd53af40d

Draw Cache: extract tris in parallel ranges

The `ibo.tris` extraction in multithread is currently only done if the
mesh has only 1 material.

Now we cache a map indicating the index of each polygon after sort and
thus allow the extraction of tris with materials in multithreaded.

As caching is a heavy operation and was already being performed in
multi-thread for triangle offsets, no significant improvements are
expected.

The benefit will be much greater when we can skip updating the cache
while transforming a geometry.

**Profiling:**
||master:|PATCH:
|---|---|---|
|large_mesh_editing_materials:|Average: 13.855380 FPS|Average: 15.525684 FPS
||rdata 9ms iter 36ms (frame 71ms)|rdata 9ms iter 29ms (frame 64ms)
|subdiv_mesh_final_only_materials:|Average: 28.113742 FPS|Average: 28.633599 FPS
||rdata 0ms iter 1ms (frame 36ms)|rdata 0ms iter 1ms (frame 35ms)

1.1x overall speedup

Differential Revision: https://developer.blender.org/D11445

===================================================================

M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.cc
M	source/blender/draw/intern/draw_cache_extract_mesh_private.h
M	source/blender/draw/intern/draw_cache_extract_mesh_render_data.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc

===================================================================

diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index f2f769534ca..7dc468d1a73 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -84,9 +84,9 @@ typedef enum eMRDataType {
   MR_DATA_LOOSE_GEOM = 1 << 4,
   /** Force loop normals calculation. */
   MR_DATA_TAN_LOOP_NOR = 1 << 5,
-  MR_DATA_MAT_OFFSETS = 1 << 6,
+  MR_DATA_POLYS_SORTED = 1 << 6,
 } eMRDataType;
-ENUM_OPERATORS(eMRDataType, MR_DATA_MAT_OFFSETS)
+ENUM_OPERATORS(eMRDataType, MR_DATA_POLYS_SORTED)
 
 #ifdef __cplusplus
 extern "C" {
@@ -170,10 +170,10 @@ typedef struct MeshBufferExtractionCache {
   } loose_geom;
 
   struct {
-    int *tri;
+    int *tri_first_index;
+    int *mat_tri_len;
     int visible_tri_len;
-  } mat_offsets;
-
+  } poly_sorted;
 } MeshBufferExtractionCache;
 
 #define FOREACH_MESH_BUFFER_CACHE(batch_cache, mbc) \
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc
index 1a602b5b8da..b1ea17927c0 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc
@@ -532,7 +532,7 @@ 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_loose_geom(mr, update_task_data->cache, iter_type, data_flag);
-  mesh_render_data_update_mat_offsets(mr, update_task_data->cache, data_flag);
+  mesh_render_data_update_polys_sorted(mr, update_task_data->cache, data_flag);
 }
 
 static struct TaskNode *mesh_extract_render_data_node_create(struct TaskGraph *task_graph,
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 f83f4bea9af..06f040d7edf 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh_private.h
+++ b/source/blender/draw/intern/draw_cache_extract_mesh_private.h
@@ -101,10 +101,12 @@ typedef struct MeshRenderData {
   float (*loop_normals)[3];
   float (*poly_normals)[3];
   int *lverts, *ledges;
+
   struct {
-    int *tri;
+    int *tri_first_index;
+    int *mat_tri_len;
     int visible_tri_len;
-  } mat_offsets;
+  } poly_sorted;
 } MeshRenderData;
 
 BLI_INLINE BMFace *bm_original_face_get(const MeshRenderData *mr, int idx)
@@ -254,9 +256,9 @@ void mesh_render_data_update_loose_geom(MeshRenderData *mr,
                                         MeshBufferExtractionCache *cache,
                                         const eMRIterType iter_type,
                                         const eMRDataType data_flag);
-void mesh_render_data_update_mat_offsets(MeshRenderData *mr,
-                                         MeshBufferExtractionCache *cache,
-                                         const eMRDataType data_flag);
+void mesh_render_data_update_polys_sorted(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 bec21bd5a8c..297d61babb0 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
@@ -25,6 +25,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_alloca.h"
 #include "BLI_bitmap.h"
 #include "BLI_math.h"
 #include "BLI_task.h"
@@ -179,116 +180,104 @@ void mesh_render_data_update_loose_geom(MeshRenderData *mr,
 /** \} */
 
 /* ---------------------------------------------------------------------- */
-/** \name Material Offsets
+/** \name Polygons sorted per material
  *
- * Material offsets contains the offset of a material after sorting tris based on their material.
+ * Contains polygon indices sorted 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,
+static void mesh_render_data_polys_sorted_load(MeshRenderData *mr,
+                                               const MeshBufferExtractionCache *cache);
+static void mesh_render_data_polys_sorted_ensure(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)
+static void mesh_render_data_polys_sorted_build(MeshRenderData *mr,
+                                                MeshBufferExtractionCache *cache);
+static int *mesh_render_data_mat_tri_len_build(MeshRenderData *mr);
+
+void mesh_render_data_update_polys_sorted(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);
+  if (data_flag & MR_DATA_POLYS_SORTED) {
+    mesh_render_data_polys_sorted_ensure(mr, cache);
+    mesh_render_data_polys_sorted_load(mr, cache);
   }
 }
 
-static void mesh_render_data_mat_offset_load(MeshRenderData *mr,
-                                             const MeshBufferExtractionCache *cache)
+static void mesh_render_data_polys_sorted_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;
+  mr->poly_sorted.tri_first_index = cache->poly_sorted.tri_first_index;
+  mr->poly_sorted.mat_tri_len = cache->poly_sorted.mat_tri_len;
+  mr->poly_sorted.visible_tri_len = cache->poly_sorted.visible_tri_len;
 }
 
-static void mesh_render_data_mat_offset_ensure(MeshRenderData *mr,
-                                               MeshBufferExtractionCache *cache)
+static void mesh_render_data_polys_sorted_ensure(MeshRenderData *mr,
+                                                 MeshBufferExtractionCache *cache)
 {
-  if (cache->mat_offsets.tri) {
+  if (cache->poly_sorted.tri_first_index) {
     return;
   }
-  mesh_render_data_mat_offset_build(mr, cache);
+  mesh_render_data_polys_sorted_build(mr, cache);
 }
 
-static void mesh_render_data_mat_offset_build(MeshRenderData *mr, MeshBufferExtractionCache *cache)
+static void mesh_render_data_polys_sorted_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__);
+  int *tri_first_index = MEM_mallocN(sizeof(*tri_first_index) * mr->poly_len, __func__);
+  int *mat_tri_len = mesh_render_data_mat_tri_len_build(mr);
+
+  /* Apply offset. */
+  int visible_tri_len = 0;
+  int *mat_tri_offs = BLI_array_alloca(mat_tri_offs, mr->mat_len);
+  {
+    for (int i = 0; i < mr->mat_len; i++) {
+      mat_tri_offs[i] = visible_tri_len;
+      visible_tri_len += mat_tri_len[i];
+    }
+  }
 
-  /* Count how many triangles for each material. */
+  /* Sort per material. */
+  int mat_last = mr->mat_len - 1;
   if (mr->extract_type == MR_EXTRACT_BMESH) {
-    mesh_render_data_mat_offset_build_bm(mr, cache);
+    BMIter iter;
+    BMFace *f;
+    int i;
+    BM_ITER_MESH_INDEX (f, &iter, mr->bm, BM_FACES_OF_MESH, i) {
+      if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+        const int mat = min_ii(f->mat_nr, mat_last);
+        tri_first_index[i] = mat_tri_offs[mat];
+        mat_tri_offs[mat] += f->len - 2;
+      }
+      else {
+        tri_first_index[i] = -1;
+      }
+    }
   }
   else {
-    mesh_render_data_mat_offset_build_mesh(mr, cache);
-  }
-
-  mesh_render_data_mat_offset_apply_offset(mr, cache);
-}
-
-typedef struct MatOffsetUserData {
-  MeshRenderData *mr;
-  /** This struct is extended during allocation to hold mat_tri_len for each material. */
-  int mat_tri_len[0];
-} MatOffsetUserData;
-
-static void mesh_render_data_mat_offset_reduce(const void *__restrict UNUSED(userdata),
-                                               void *__restrict chunk_join,
-                                               void *__restrict chunk)
-{
-  MatOffsetUserData *dst = chunk_join;
-  MatOffsetUserData *src = chunk;
-  int *dst_mat_len = dst->mat_tri_len;
-  int *src_mat_len = src->mat_tri_len;
-  for (int i = 0; i < dst->mr->mat_len; i++) {
-    dst_mat_len[i] += src_mat_len[i];
+    const MPoly *mp = &mr->mpoly[0];
+    for (int i = 0; i < mr->poly_len; i++, mp++) {
+      if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
+        const int mat = min_ii(mp->mat_nr, mat_last);
+        tri_first_index[i] = mat_tri_offs[mat];
+        mat_tri_offs[mat] += mp->totloop - 2;
+      }
+      else {
+        tri_first_index[i] = -1;
+      }
+    }
   }
-}
-
-static void mesh_render_data_mat_offset_build_threaded(MeshRenderData *mr,
-                        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list