[Bf-blender-cvs] [285a68b7bbf] master: Sculpt: PBVH Draw Support for EEVEE

Joseph Eagar noreply at git.blender.org
Wed Jun 8 21:32:06 CEST 2022


Commit: 285a68b7bbf2fa40e41d507991467387f5dd5264
Author: Joseph Eagar
Date:   Wed Jun 8 12:30:01 2022 -0700
Branches: master
https://developer.blender.org/rB285a68b7bbf2fa40e41d507991467387f5dd5264

Sculpt: PBVH Draw Support for EEVEE

This patch adds support for PBVH drawing in EEVEE.

Notes:
  # PBVH_FACES only.  For Multires we'll need an API to get/cache attributes.  DynTopo support will be merged in later with sculpt-dev's DynTopo implementation.
  # Supports vertex color and UV attributes only; other types can be added fairly easily though.
  # Workbench only sends the active vertex color and UV layers to the GPU.
  # Added a new draw engine API method, DRW_cdlayer_attr_aliases_add.  Please review.
  # The vertex format object is now stored in the pbvh.

Reviewed By: Clément Foucault & Brecht Van Lommel & Jeroen Bakker
Differential Revision: https://developer.blender.org/D13897
Ref D13897

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/draw/DRW_engine.h
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache_impl_mesh.cc
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 7a89dee4148..f517ff3a949 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -221,7 +221,8 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
                       PBVHFrustumPlanes *update_frustum,
                       PBVHFrustumPlanes *draw_frustum,
                       void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers),
-                      void *user_data);
+                      void *user_data,
+                      bool full_render);
 
 void BKE_pbvh_draw_debug_cb(
     PBVH *pbvh,
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 1016d91614b..c9f60356451 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -2293,8 +2293,8 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *v3d)
 
   if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
     /* Regular mesh only draws from PBVH without modifiers and shape keys. */
-    const bool full_shading = (v3d && (v3d->shading.type > OB_SOLID));
-    return !(ss->shapekey_active || ss->deform_modifiers_active || full_shading);
+
+    return !(ss->shapekey_active || ss->deform_modifiers_active);
   }
 
   /* Multires and dyntopo always draw directly from the PBVH. */
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index cdc4dfdccff..8c9db339753 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -714,6 +714,10 @@ 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);
 }
 
@@ -1299,6 +1303,17 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
   PBVH *pbvh = data->pbvh;
   PBVHNode *node = data->nodes[n];
 
+  CustomData *vdata, *ldata;
+
+  if (!pbvh->bm) {
+    vdata = pbvh->vdata;
+    ldata = pbvh->ldata;
+  }
+  else {
+    vdata = &pbvh->bm->vdata;
+    ldata = &pbvh->bm->ldata;
+  }
+
   if (node->flag & PBVH_RebuildDrawBuffers) {
     switch (pbvh->type) {
       case PBVH_GRIDS:
@@ -1326,7 +1341,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
     const int update_flags = pbvh_get_buffers_update_flags(pbvh);
     switch (pbvh->type) {
       case PBVH_GRIDS:
-        GPU_pbvh_grid_buffers_update(node->draw_buffers,
+        GPU_pbvh_grid_buffers_update(pbvh->vbo_id,
+                                     node->draw_buffers,
                                      pbvh->subdiv_ccg,
                                      pbvh->grids,
                                      pbvh->grid_flag_mats,
@@ -1339,26 +1355,22 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
                                      update_flags);
         break;
       case PBVH_FACES: {
-        CustomDataLayer *layer = NULL;
-        eAttrDomain domain;
-
-        BKE_pbvh_get_color_layer(pbvh->mesh, &layer, &domain);
-
-        GPU_pbvh_mesh_buffers_update(node->draw_buffers,
+        GPU_pbvh_mesh_buffers_update(pbvh->vbo_id,
+                                     node->draw_buffers,
                                      pbvh->verts,
-                                     pbvh->vert_normals,
+                                     vdata,
+                                     ldata,
                                      CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK),
-                                     layer ? layer->data : NULL,
-                                     layer ? layer->type : -1,
-                                     layer ? domain : ATTR_DOMAIN_AUTO,
                                      CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS),
                                      pbvh->face_sets_color_seed,
                                      pbvh->face_sets_color_default,
-                                     update_flags);
+                                     update_flags,
+                                     pbvh->vert_normals);
         break;
       }
       case PBVH_BMESH:
-        GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
+        GPU_pbvh_bmesh_buffers_update(pbvh->vbo_id,
+                                      node->draw_buffers,
                                       pbvh->bm,
                                       node->bm_faces,
                                       node->bm_unique_verts,
@@ -1379,8 +1391,49 @@ void pbvh_free_draw_buffers(PBVH *pbvh, PBVHNode *node)
   }
 }
 
-static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag)
+static void pbvh_update_draw_buffers(
+    PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag, bool full_render)
 {
+  const CustomData *vdata;
+  const CustomData *ldata;
+
+  if (!pbvh->vbo_id) {
+    pbvh->vbo_id = GPU_pbvh_make_format();
+  }
+
+  switch (pbvh->type) {
+    case PBVH_BMESH:
+      if (!pbvh->bm) {
+        /* BMesh hasn't been created yet */
+        return;
+      }
+
+      vdata = &pbvh->bm->vdata;
+      ldata = &pbvh->bm->ldata;
+      break;
+    case PBVH_FACES:
+      vdata = pbvh->vdata;
+      ldata = pbvh->ldata;
+      break;
+    case PBVH_GRIDS:
+      ldata = vdata = NULL;
+      break;
+  }
+
+  const bool active_attrs_only = !full_render;
+
+  /* rebuild all draw buffers if attribute layout changed */
+  if (GPU_pbvh_attribute_names_update(pbvh->type, pbvh->vbo_id, vdata, ldata, active_attrs_only)) {
+    /* attribute layout changed; force rebuild */
+    for (int i = 0; i < pbvh->totnode; i++) {
+      PBVHNode *node = pbvh->nodes + i;
+
+      if (node->flag & PBVH_Leaf) {
+        node->flag |= PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw;
+      }
+    }
+  }
+
   if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) {
     /* Free buffers uses OpenGL, so not in parallel. */
     for (int n = 0; n < totnode; n++) {
@@ -2783,8 +2836,11 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
                       PBVHFrustumPlanes *update_frustum,
                       PBVHFrustumPlanes *draw_frustum,
                       void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers),
-                      void *user_data)
+                      void *user_data,
+                      bool full_render)
 {
+  pbvh->draw_cache_invalid = false;
+
   PBVHNode **nodes;
   int totnode;
   int update_flag = 0;
@@ -2808,7 +2864,7 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
 
   /* Update draw buffers. */
   if (totnode != 0 && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) {
-    pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag);
+    pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag, full_render);
   }
   MEM_SAFE_FREE(nodes);
 
@@ -3156,6 +3212,11 @@ bool BKE_pbvh_is_drawing(const PBVH *pbvh)
   return pbvh->is_drawing;
 }
 
+bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh)
+{
+  return pbvh->draw_cache_invalid;
+}
+
 void BKE_pbvh_is_drawing_set(PBVH *pbvh, bool val)
 {
   pbvh->is_drawing = val;
@@ -3229,8 +3290,3 @@ void BKE_pbvh_ensure_node_loops(PBVH *pbvh)
 
   MEM_SAFE_FREE(visit);
 }
-
-bool BKE_pbvh_draw_cache_invalid(const PBVH *pbvh)
-{
-  return pbvh->draw_cache_invalid;
-}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index d4c6dcfbc96..112fd01c699 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -376,6 +376,9 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index)
     return false;
   }
 
+  /* Trigger draw manager cache invalidation. */
+  pbvh->draw_cache_invalid = true;
+
   /* For each BMFace, store the AABB and AABB centroid */
   BBC *bbc_array = MEM_mallocN(sizeof(BBC) * bm_faces_size, "BBC");
 
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index 98b490b28dd..a4ac2744a73 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -2,6 +2,8 @@
 
 #pragma once
 
+struct PBVHGPUFormat;
+
 /** \file
  * \ingroup bke
  */
@@ -123,9 +125,7 @@ struct PBVHNode {
   PBVHPixelsNode pixels;
 };
 
-typedef enum {
-  PBVH_DYNTOPO_SMOOTH_SHADING = 1,
-} PBVHFlags;
+typedef enum { PBVH_DYNTOPO_SMOOTH_SHADING = 1 } PBVHFlags;
 
 typedef struct PBVHBMeshLog PBVHBMeshLog;
 
@@ -204,6 +204,8 @@ struct PBVH {
 
   /* Used by DynTopo to invalidate the draw cache. */
   bool draw_cache_invalid;
+
+  struct PBVHGPUFormat *vbo_id;
 };
 
 /* pbvh.c */
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 00822946fe5..5b3d262ac66 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -23,6 +23,9 @@ struct DrawEngineType;
 struct GHash;
 struct GPUMaterial;
 struct GPUOffScreen;
+struct GPUVertFormat;
+struct CustomDataLayer;
+struct CustomData;
 struct GPUViewport;
 struct ID;
 struct Main;
@@ -218,6 +221,12 @@ void DRW_opengl_context_activate(bool drw_state);
  */
 void DRW_draw_cursor_2d_ex(const struct ARegion *region, const float cursor[2]);
 
+void DRW_cdlayer_attr_aliases_add(struct GPUVertFormat *format,
+                                  char *base_name,
+                                  const struct CustomData *data,
+                                  const struct CustomDataLayer *cl,
+                                  bool is_active_render,
+                                  bool is_active_layer);
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index fb20bde2f65..9eb35c25bf4 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -97,7 +97,7 @@ static void workbench_cache_sculpt_populate(WORKBENCH_PrivateData *wpd,
 {
   const bool use_single_drawcall = !ELEM(color_type, V3D_SHADING_MATERIAL_COLOR);
   if (use_single_drawcall) {
-    DRWShadingGroup *grp = workbench_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list