[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