[Bf-blender-cvs] [bf34b0c8f4b] master: DrawManager: Graph Task Scheduling

Jeroen Bakker noreply at git.blender.org
Tue Jun 2 15:55:37 CEST 2020


Commit: bf34b0c8f4b8c64bcc4ec0f3371d343e9c2fe029
Author: Jeroen Bakker
Date:   Tue Jun 2 15:07:17 2020 +0200
Branches: master
https://developer.blender.org/rBbf34b0c8f4b8c64bcc4ec0f3371d343e9c2fe029

DrawManager: Graph Task Scheduling

This patch uses a graph flow scheduler for creating all mesh batches.
On a Ryzen 1700 the framerate of Spring/020_02A.anim.blend went from 10 fps to 11.5 fps.

For each mesh where batches needs to be updated a sub-graph will be added to the task_graph.
This sub-graph starts with an extract_render_data_node. This fills/converts the required data
from Mesh.

Small extractions and extractions that can't be multi-threaded are grouped in a single
`extract_single_threaded_task_node`.

Other extractions will create a node for each loop exceeding 4096 items. these nodes are
linked to the `user_data_init_task_node`. the `user_data_init_task_node` prepares the userdata
needed for the extraction based on the data extracted from the mesh.

Note: If the `lines` and `lines_loose` are requested, the `lines_loose` sub-buffer is created
as part of the lines extraction. When the lines_loose is only requested the sub-buffer is
created from the existing `lines` buffer. It is assumed that the lines buffer is always
requested before or together with the lines_loose what is always the case (see
`DRW_batch_requested(cache->batch.loose_edges, GPU_PRIM_LINES)` in `draw_cache_impl_mesh.c`).

Reviewed By: Clément Foucault

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

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

M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_manager.h
M	source/blender/editors/uvedit/uvedit_draw.c

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

diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index e6e66eea32f..e4088b5654f 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -696,6 +696,8 @@ typedef struct DRWContextState {
 
   struct Depsgraph *depsgraph;
 
+  struct TaskGraph *task_graph;
+
   eObjectMode object_mode;
 
   eGPUShaderConfig sh_cfg;
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 23d0d74534d..c23ea3d7c82 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -3534,13 +3534,15 @@ void drw_batch_cache_generate_requested(Object *ob)
   struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   switch (ob->type) {
     case OB_MESH:
-      DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
+      DRW_mesh_batch_cache_create_requested(
+          DST.task_graph, ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
       break;
     case OB_CURVE:
     case OB_FONT:
     case OB_SURF:
       if (mesh_eval) {
-        DRW_mesh_batch_cache_create_requested(ob, mesh_eval, scene, is_paint_mode, use_hide);
+        DRW_mesh_batch_cache_create_requested(
+            DST.task_graph, ob, mesh_eval, scene, is_paint_mode, use_hide);
       }
       DRW_curve_batch_cache_create_requested(ob);
       break;
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index b2fea957227..f203c2ff1ea 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -23,6 +23,8 @@
 #ifndef __DRAW_CACHE_EXTRACT_H__
 #define __DRAW_CACHE_EXTRACT_H__
 
+struct TaskGraph;
+
 /* Vertex Group Selection and display options */
 typedef struct DRW_MeshWeightState {
   int defgroup_active;
@@ -249,7 +251,8 @@ typedef struct MeshBatchCache {
   bool no_loose_wire;
 } MeshBatchCache;
 
-void mesh_buffer_cache_create_requested(MeshBatchCache *cache,
+void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph,
+                                        MeshBatchCache *cache,
                                         MeshBufferCache mbc,
                                         Mesh *me,
                                         const bool is_editmode,
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index cbb5f5f06ff..916ee9fe576 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -134,15 +134,12 @@ typedef struct MeshRenderData {
   float (*poly_normals)[3];
   int *lverts, *ledges;
 } MeshRenderData;
-
 static MeshRenderData *mesh_render_data_create(Mesh *me,
                                                const bool is_editmode,
                                                const bool is_paint_mode,
                                                const float obmat[4][4],
                                                const bool do_final,
                                                const bool do_uvedit,
-                                               const eMRIterType iter_type,
-                                               const eMRDataType data_flag,
                                                const DRW_MeshCDMask *UNUSED(cd_used),
                                                const ToolSettings *ts)
 {
@@ -152,9 +149,6 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
 
   copy_m4_m4(mr->obmat, obmat);
 
-  const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
-  const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
-
   if (is_editmode) {
     BLI_assert(me->edit_mesh->mesh_eval_cage && me->edit_mesh->mesh_eval_final);
     mr->bm = me->edit_mesh->bm;
@@ -244,7 +238,32 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
     mr->v_origindex = CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX);
     mr->e_origindex = CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX);
     mr->p_origindex = CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX);
+  }
+  else {
+    /* BMesh */
+    BMesh *bm = mr->bm;
+
+    mr->vert_len = bm->totvert;
+    mr->edge_len = bm->totedge;
+    mr->loop_len = bm->totloop;
+    mr->poly_len = bm->totface;
+    mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
+  }
+
+  return mr;
+}
 
+/* Part of the creation of the MeshRenderData that happens in a thread. */
+static void mesh_render_data_update(MeshRenderData *mr,
+                                    const eMRIterType iter_type,
+                                    const eMRDataType data_flag)
+{
+  Mesh *me = mr->me;
+  const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
+  const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
+
+  if (mr->extract_type != MR_EXTRACT_BMESH) {
+    /* Mesh */
     if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
       mr->poly_normals = MEM_mallocN(sizeof(*mr->poly_normals) * mr->poly_len, __func__);
       BKE_mesh_calc_normals_poly((MVert *)mr->mvert,
@@ -323,13 +342,6 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
   else {
     /* BMesh */
     BMesh *bm = mr->bm;
-
-    mr->vert_len = bm->totvert;
-    mr->edge_len = bm->totedge;
-    mr->loop_len = bm->totloop;
-    mr->poly_len = bm->totface;
-    mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len);
-
     if (data_flag & MR_DATA_POLY_NOR) {
       /* Use bmface->no instead. */
     }
@@ -394,7 +406,6 @@ static MeshRenderData *mesh_render_data_create(Mesh *me,
       mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2;
     }
   }
-  return mr;
 }
 
 static void mesh_render_data_free(MeshRenderData *mr)
@@ -742,46 +753,15 @@ static const MeshExtract extract_lines = {
     0,
     false,
 };
-
 /** \} */
 
 /* ---------------------------------------------------------------------- */
-/** \name Extract Loose Edges Indices
+/** \name Extract Loose Edges Sub Buffer
  * \{ */
 
-static void *extract_lines_loose_init(const MeshRenderData *UNUSED(mr), void *UNUSED(buf))
-{
-  return NULL;
-}
-
-static void extract_lines_loose_ledge_mesh(const MeshRenderData *UNUSED(mr),
-                                           int UNUSED(e),
-                                           const MEdge *UNUSED(medge),
-                                           void *UNUSED(elb))
-{
-  /* This function is intentionally empty. The existence of this functions ensures that
-   * `iter_type` `MR_ITER_LVERT` is set when initializing the `MeshRenderData` (See
-   * `mesh_extract_iter_type`). This flag ensures that `mr->edge_loose_len` field is filled. This
-   * field we use in the `extract_lines_loose_finish` function to create a subrange from the
-   * `ibo.lines`. */
-}
-
-static void extract_lines_loose_ledge_bmesh(const MeshRenderData *UNUSED(mr),
-                                            int UNUSED(e),
-                                            BMEdge *UNUSED(eed),
-                                            void *UNUSED(elb))
-{
-  /* This function is intentionally empty. The existence of this functions ensures that
-   * `iter_type` `MR_ITER_LVERT` is set when initializing the `MeshRenderData` (See
-   * `mesh_extract_iter_type`). This flag ensures that `mr->edge_loose_len` field is filled. This
-   * field we use in the `extract_lines_loose_finish` function to create a subrange from the
-   * `ibo.lines`. */
-}
-
-static void extract_lines_loose_finish(const MeshRenderData *mr,
-                                       void *UNUSED(ibo),
-                                       void *UNUSED(elb))
+static void extract_lines_loose_subbuffer(const MeshRenderData *mr)
 {
+  BLI_assert(mr->cache->final.ibo.lines);
   /* Multiply by 2 because these are edges indices. */
   const int start = mr->edge_len * 2;
   const int len = mr->edge_loose_len * 2;
@@ -790,17 +770,24 @@ static void extract_lines_loose_finish(const MeshRenderData *mr,
   mr->cache->no_loose_wire = (len == 0);
 }
 
-static const MeshExtract extract_lines_loose = {
-    extract_lines_loose_init,
-    NULL,
-    NULL,
+static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr, void *ibo, void *elb)
+{
+  GPU_indexbuf_build_in_place(elb, ibo);
+  extract_lines_loose_subbuffer(mr);
+  MEM_freeN(elb);
+}
+
+static const MeshExtract extract_lines_with_lines_loose = {
+    extract_lines_init,
     NULL,
     NULL,
-    extract_lines_loose_ledge_bmesh,
-    extract_lines_loose_ledge_mesh,
+    extract_lines_loop_bmesh,
+    extract_lines_loop_mesh,
+    extract_lines_ledge_bmesh,
+    extract_lines_ledge_mesh,
     NULL,
     NULL,
-    extract_lines_loose_finish,
+    extract_lines_with_lines_loose_finish,
     0,
     false,
 };
@@ -1716,8 +1703,8 @@ static void extract_lnor_hq_loop_mesh(
   }
 
   /* Flag for paint mode overlay.
-   * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. In paint
-   * mode it will use the unmapped data to draw the wireframe. */
+   * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. In
+   * paint mode it will use the unmapped data to draw the wireframe. */
   if (mpoly->flag & ME_HIDE ||
       (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
        mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) {
@@ -1795,8 +1782,8 @@ static void extract_lnor_loop_mesh(
   }
 
   /* Flag for paint mode overlay.
-   * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. In paint
-   * mode it will use the unmapped data to draw the wireframe. */
+   * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. In
+   * paint mode it will use the unmapped data to draw the wireframe. */
   if (mpoly->flag & ME_HIDE ||
       (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
        mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) {
@@ -4522,10 +4509,14 @@ static const MeshExtract extract_fdot_idx = {
 /** \} */
 
 /* -------------

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list