[Bf-blender-cvs] [65900d88a83] master: Sculpt: Rewrite PBVH draw

Joseph Eagar noreply at git.blender.org
Thu Sep 29 00:00:33 CEST 2022


Commit: 65900d88a8317c207885ae4a3993272112114f36
Author: Joseph Eagar
Date:   Wed Sep 28 14:51:23 2022 -0700
Branches: master
https://developer.blender.org/rB65900d88a8317c207885ae4a3993272112114f36

Sculpt: Rewrite PBVH draw

Rewrite PBVH draw to allocate attributes into individual VBOs.
The old system tried to create a single VBO that could feed
every open viewport.  This required uploading every color and
UV attribute  to the viewport whether needed or not, often exceeding
the VBO limit.

This new system creates one VBO per attribute.  Each attribute layout is
given its own GPU batch which is cached inside the owning PBVH node.

Notes:

* This is a full C++ rewrite.  The old code is still there; ripping it out
can happen later.
* PBVH nodes now have a collection of batches, PBVHBatches, that keeps
track of all the batches inside the node.
* Batches are built exclusively from a list of attributes.
* Each attribute has its own VBO.
* Overlays, workbench and EEVEE can all have different attribute
  layouts, each of which will get its own batch.

Reviewed by: Clement Foucault
Differential Revision: https://developer.blender.org/D15428
Ref D15428

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh.cc
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenlib/BLI_math_vec_types.hh
M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/DRW_pbvh.h
M	source/blender/draw/engines/basic/basic_engine.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/overlay/overlay_facing.cc
M	source/blender/draw/engines/overlay/overlay_fade.cc
M	source/blender/draw/engines/overlay/overlay_mode_transfer.cc
M	source/blender/draw/engines/overlay/overlay_sculpt.cc
M	source/blender/draw/engines/overlay/overlay_wireframe.cc
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_attributes.h
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache_extract.hh
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.cc
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
A	source/blender/draw/intern/draw_pbvh.cc
A	source/blender/draw/intern/draw_pbvh.h
M	source/blender/gpu/CMakeLists.txt
D	source/blender/gpu/GPU_buffers.h
D	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_init_exit.c

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 22e4a2bce87..0e172abd9a2 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -450,6 +450,7 @@ int CustomData_get_stencil_layer(const struct CustomData *data, int type);
  * if no such active layer is defined.
  */
 const char *CustomData_get_active_layer_name(const struct CustomData *data, int type);
+const char *CustomData_get_render_layer_name(const struct CustomData *data, int type);
 
 /**
  * Returns name of the default layer of the given type or NULL
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index ff2140732cc..9e0884a8c76 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -16,6 +16,7 @@
 /* For embedding CCGKey in iterator. */
 #include "BKE_attribute.h"
 #include "BKE_ccg.h"
+#include "DNA_customdata_types.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -27,7 +28,6 @@ struct CCGElem;
 struct CCGKey;
 struct CustomData;
 struct DMFlagMat;
-struct GPU_PBVH_Buffers;
 struct IsectRayPrecalc;
 struct MLoop;
 struct MLoopTri;
@@ -36,7 +36,9 @@ struct MVert;
 struct Mesh;
 struct MeshElemMap;
 struct PBVH;
+struct PBVHBatches;
 struct PBVHNode;
+struct PBVH_GPU_Args;
 struct SubdivCCG;
 struct TaskParallelSettings;
 struct Image;
@@ -98,6 +100,12 @@ typedef struct PBVHPixelsNode {
   void *node_data;
 } PBVHPixelsNode;
 
+typedef struct PBVHAttrReq {
+  char name[MAX_CUSTOMDATA_LAYER_NAME];
+  eAttrDomain domain;
+  eCustomDataType type;
+} PBVHAttrReq;
+
 typedef enum {
   PBVH_Leaf = 1 << 0,
 
@@ -348,9 +356,13 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
                       bool update_only_visible,
                       PBVHFrustumPlanes *update_frustum,
                       PBVHFrustumPlanes *draw_frustum,
-                      void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers),
+                      void (*draw_fn)(void *user_data,
+                                      struct PBVHBatches *batches,
+                                      struct PBVH_GPU_Args *args),
                       void *user_data,
-                      bool full_render);
+                      bool full_render,
+                      PBVHAttrReq *attrs,
+                      int attrs_num);
 
 void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
                             void (*draw_fn)(PBVHNode *node,
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 1d65e958e1c..a1de8e40fe3 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -25,9 +25,9 @@
 #include "BKE_pbvh.h"
 #include "BKE_subdiv_ccg.h"
 
-#include "PIL_time.h"
+#include "DRW_pbvh.h"
 
-#include "GPU_buffers.h"
+#include "PIL_time.h"
 
 #include "bmesh.h"
 
@@ -513,6 +513,80 @@ static void pbvh_build(PBVH *pbvh, BB *cb, BBC *prim_bbc, int totprim)
   build_sub(pbvh, 0, cb, prim_bbc, 0, totprim);
 }
 
+static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
+{
+  memset((void *)args, 0, sizeof(*args));
+
+  args->pbvh_type = pbvh->header.type;
+  args->mesh_verts_num = pbvh->totvert;
+  args->mesh_grids_num = pbvh->totgrid;
+  args->node = node;
+
+  BKE_pbvh_node_num_verts(pbvh, node, NULL, &args->node_verts_num);
+
+  args->grid_hidden = pbvh->grid_hidden;
+  args->face_sets_color_default = pbvh->face_sets_color_default;
+  args->face_sets_color_seed = pbvh->face_sets_color_seed;
+  args->mvert = pbvh->verts;
+  args->mloop = pbvh->mloop;
+  args->mpoly = pbvh->mpoly;
+  args->mlooptri = pbvh->looptri;
+
+  if (ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)) {
+    args->hide_poly = pbvh->pdata ?
+                          CustomData_get_layer_named(pbvh->pdata, CD_PROP_BOOL, ".hide_poly") :
+                          NULL;
+  }
+
+  switch (pbvh->header.type) {
+    case PBVH_FACES:
+      args->mesh_faces_num = pbvh->mesh->totpoly;
+      args->vdata = pbvh->vdata;
+      args->ldata = pbvh->ldata;
+      args->pdata = pbvh->pdata;
+      args->totprim = node->totprim;
+      args->me = pbvh->mesh;
+      args->mpoly = pbvh->mpoly;
+      args->vert_normals = pbvh->vert_normals;
+
+      args->prim_indices = node->prim_indices;
+      args->face_sets = pbvh->face_sets;
+      break;
+    case PBVH_GRIDS:
+      args->vdata = pbvh->vdata;
+      args->ldata = pbvh->ldata;
+      args->pdata = pbvh->pdata;
+      args->ccg_key = pbvh->gridkey;
+      args->me = pbvh->mesh;
+      args->totprim = node->totprim;
+      args->grid_indices = node->prim_indices;
+      args->subdiv_ccg = pbvh->subdiv_ccg;
+      args->face_sets = pbvh->face_sets;
+      args->mpoly = pbvh->mpoly;
+
+      args->mesh_grids_num = pbvh->totgrid;
+      args->grids = pbvh->grids;
+      args->gridfaces = pbvh->gridfaces;
+      args->grid_flag_mats = pbvh->grid_flag_mats;
+      args->vert_normals = pbvh->vert_normals;
+
+      args->face_sets = pbvh->face_sets;
+      break;
+    case PBVH_BMESH:
+      args->bm = pbvh->header.bm;
+      args->vdata = &args->bm->vdata;
+      args->ldata = &args->bm->ldata;
+      args->pdata = &args->bm->pdata;
+      args->bm_faces = node->bm_faces;
+      args->bm_other_verts = node->bm_other_verts;
+      args->bm_unique_vert = node->bm_unique_verts;
+      args->totprim = BLI_gset_len(node->bm_faces);
+      args->cd_mask_layer = CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK);
+
+      break;
+  }
+}
+
 void BKE_pbvh_build_mesh(PBVH *pbvh,
                          Mesh *mesh,
                          const MPoly *mpoly,
@@ -645,8 +719,8 @@ void BKE_pbvh_free(PBVH *pbvh)
     PBVHNode *node = &pbvh->nodes[i];
 
     if (node->flag & PBVH_Leaf) {
-      if (node->draw_buffers) {
-        GPU_pbvh_buffers_free(node->draw_buffers);
+      if (node->draw_batches) {
+        DRW_pbvh_node_free(node->draw_batches);
       }
       if (node->vert_indices) {
         MEM_freeN((void *)node->vert_indices);
@@ -693,10 +767,6 @@ void BKE_pbvh_free(PBVH *pbvh)
 
   MEM_SAFE_FREE(pbvh->vert_bitmap);
 
-  if (pbvh->vbo_id) {
-    GPU_pbvh_free_format(pbvh->vbo_id);
-  }
-
   MEM_freeN(pbvh);
 }
 
@@ -988,6 +1058,8 @@ typedef struct PBVHUpdateData {
   float (*vnors)[3];
   int flag;
   bool show_sculpt_face_sets;
+  PBVHAttrReq *attrs;
+  int attrs_num;
 } PBVHUpdateData;
 
 static void pbvh_update_normals_clear_task_cb(void *__restrict userdata,
@@ -1240,13 +1312,6 @@ void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
   BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings);
 }
 
-static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh))
-{
-  int update_flags = GPU_PBVH_BUFFERS_SHOW_VCOL | GPU_PBVH_BUFFERS_SHOW_MASK |
-                     GPU_PBVH_BUFFERS_SHOW_SCULPT_FACE_SETS;
-  return update_flags;
-}
-
 bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr)
 {
   CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me);
@@ -1283,128 +1348,29 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
   PBVHNode *node = data->nodes[n];
 
   if (node->flag & PBVH_RebuildDrawBuffers) {
-    switch (pbvh->header.type) {
-      case PBVH_GRIDS: {
-        bool smooth = node->totprim > 0 ?
-                          pbvh->grid_flag_mats[node->prim_indices[0]].flag & ME_SMOOTH :
-                          false;
+    PBVH_GPU_Args args;
+    pbvh_draw_args_init(pbvh, &args, node);
 
-        node->draw_buffers = GPU_pbvh_grid_buffers_build(node->totprim, pbvh->grid_hidden, smooth);
-        break;
-      }
-      case PBVH_FACES:
-        node->draw_buffers = GPU_pbvh_mesh_buffers_build(
-            pbvh->mesh, pbvh->looptri, node->prim_indices, node->totprim);
-        break;
-      case PBVH_BMESH:
-        node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
-                                                          PBVH_DYNTOPO_SMOOTH_SHADING);
-        break;
-    }
+    node->draw_batches = DRW_pbvh_node_create(&args);
   }
 
   if (node->flag & PBVH_UpdateDrawBuffers) {
     node->debug_draw_gen++;
 
-    const int update_flags = pbvh_get_buffers_update_flags(pbvh);
-    switch (pbvh->header.type) {
-      case PBVH_GRIDS:
-        GPU_pbvh_grid_buffers_update(pbvh->vbo_id,
-                                     node->draw_buffers,
-                                     pbvh->subdiv_ccg,
-                                     pbvh->grids,
-                                     pbvh->grid_flag_mats,
-                                     node->prim_indices,
-                                     node->totprim,
-                                     pbvh->face_sets,
-                                     pbvh->face_sets_color_seed,
-                                     pbvh->face_sets_color_default,
-                                     &pbvh->gridkey,
-                                     update_flags);
-        break;
-      case PBVH_FACES: {
-        /* Pass vertices separately because they may be not be the same as the mesh's vertices,
-         * and pass normals separately because they are managed by the PBVH. */
-        GPU_pbvh_mesh_buffers_update(
-            pbvh->vbo_id,
-            node->draw_buffers,
-            pbvh->mesh,
-            pbvh->verts,
-            CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
-            CustomData_get_layer_named(pbvh->pdata, CD_PROP_INT32, ".sculpt_face_set"),
-            pbvh->face_sets_color_seed,
-            pbvh->face_sets_color_default,
-            update_flags,
-            pbvh->vert_normals);
-        break;
-      }
-      case PBVH_BMESH:
-        GPU_pbvh_bmesh_buffers_update(pbvh->vbo_id,
-                                      node->draw_buffers,
-                                      pbvh->header.bm,
-                                      node->bm_faces,
-                                      node->bm_unique_verts,
-                                      node->bm_other_verts,
-                                      update_flags);
-        break;
+    if (node->draw_batches) {
+      PBVH_GPU_Args args;
+
+      pbv

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list