[Bf-blender-cvs] [eb92741c3be] temp-pbvh-vbos: Initial rough code

Joseph Eagar noreply at git.blender.org
Sun Aug 21 00:44:43 CEST 2022


Commit: eb92741c3be144d0145fc711e971b24ba06d9246
Author: Joseph Eagar
Date:   Sat Aug 6 18:27:14 2022 -0700
Branches: temp-pbvh-vbos
https://developer.blender.org/rBeb92741c3be144d0145fc711e971b24ba06d9246

Initial rough code

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_batch.h
M	source/blender/gpu/GPU_buffers.h
R083	source/blender/gpu/intern/gpu_buffers.c	source/blender/gpu/intern/gpu_buffers.cc

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index af7effe806c..128834ba4ba 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" {
@@ -98,6 +99,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,7 +355,9 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
                       PBVHFrustumPlanes *draw_frustum,
                       void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers),
                       void *user_data,
-                      bool full_render);
+                      bool full_render,
+                      PBVHAttrReq *attrs,
+                      int attrs_num);
 
 void BKE_pbvh_draw_debug_cb(
     PBVH *pbvh,
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index dae9788d21c..dfd3c81789c 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1009,6 +1009,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,
@@ -2830,6 +2832,8 @@ void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default)
 typedef struct PBVHDrawSearchData {
   PBVHFrustumPlanes *frustum;
   int accum_update_flag;
+  PBVHAttrReq *attrs;
+  int attrs_num;
 } PBVHDrawSearchData;
 
 static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v)
@@ -2849,7 +2853,9 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
                       PBVHFrustumPlanes *draw_frustum,
                       void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers),
                       void *user_data,
-                      bool UNUSED(full_render))
+                      bool UNUSED(full_render),
+                      PBVHAttrReq *attrs,
+                      int attrs_num)
 {
   PBVHNode **nodes;
   int totnode;
@@ -2860,7 +2866,8 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
   /* Search for nodes that need updates. */
   if (update_only_visible) {
     /* Get visible nodes with draw updates. */
-    PBVHDrawSearchData data = {.frustum = update_frustum, .accum_update_flag = 0};
+    PBVHDrawSearchData data = {
+        .frustum = update_frustum, .accum_update_flag = 0, attrs, attrs_num};
     BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode);
     update_flag = data.accum_update_flag;
   }
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 9392efcf92b..926e495dc5b 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -1283,7 +1283,9 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd)
                    &draw_frustum,
                    (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb,
                    scd,
-                   scd->use_mats);
+                   scd->use_mats,
+                   NULL,
+                   0);
 
   if (SCULPT_DEBUG_BUFFERS) {
     int debug_node_nr = 0;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 4157caf45d7..d079ea7cad6 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -47,7 +47,7 @@ set(SRC
   intern/gpu_batch.cc
   intern/gpu_batch_presets.c
   intern/gpu_batch_utils.c
-  intern/gpu_buffers.c
+  intern/gpu_buffers.cc
   intern/gpu_capabilities.cc
   intern/gpu_codegen.cc
   intern/gpu_compute.cc
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 7ef2d81ac31..101a53fab9d 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -93,8 +93,9 @@ void GPU_batch_init_ex(GPUBatch *batch,
  */
 void GPU_batch_copy(GPUBatch *batch_dst, GPUBatch *batch_src);
 
-#define GPU_batch_create(prim, verts, elem) GPU_batch_create_ex(prim, verts, elem, 0)
-#define GPU_batch_init(batch, prim, verts, elem) GPU_batch_init_ex(batch, prim, verts, elem, 0)
+#define GPU_batch_create(prim, verts, elem) GPU_batch_create_ex(prim, verts, elem, (eGPUBatchFlag)0)
+#define GPU_batch_init(batch, prim, verts, elem) \
+  GPU_batch_init_ex(batch, prim, verts, elem, (eGPUBatchFlag)0)
 
 /**
  * Same as discard but does not free. (does not call free callback).
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 6dc49ff494d..b78e4235945 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -34,6 +34,31 @@ struct PBVH;
 struct SubdivCCG;
 struct CustomData;
 
+typedef struct PBVH_GPU_Args {
+  PBVHType pbvh_type;
+
+  struct BMesh *bm;
+  struct Mesh *me;
+  struct MVert *mvert;
+  int verts_num, faces_num, grids_num;
+  struct CustomData *vdata, *ldata, *pdata;
+  const float (*vert_normals)[3];
+
+  int face_sets_color_seed, face_sets_color_default;
+
+  const struct DMFlagMat *grid_flag_mats;
+  const int *grid_indices;
+  const struct CCGKey *ccg_key;
+
+  int *prim_indicies;
+  int totprim;
+
+  int node_verts_num;
+
+  struct GSet *bm_unique_vert, *bm_other_verts, *bm_faces;
+  struct MLoopTri *mlooptri;
+} PBVH_GPU_Args;
+
 typedef struct PBVHGPUFormat PBVHGPUFormat;
 
 /**
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.cc
similarity index 83%
rename from source/blender/gpu/intern/gpu_buffers.c
rename to source/blender/gpu/intern/gpu_buffers.cc
index 2a0f624ac45..862ba66c7e5 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.cc
@@ -40,6 +40,359 @@
 
 #include "bmesh.h"
 
+#define MAX_PBVH_BATCH_KEY 512
+#define MAX_PBVH_VBOS 16
+
+#include "BLI_index_range.hh"
+#include "BLI_map.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_vector.hh"
+#include <vector>
+
+#include <algorithm>
+#include <string>
+
+using blender::float2;
+using blender::float3;
+using blender::float4;
+using blender::IndexRange;
+using blender::Map;
+using blender::Vector;
+
+using string = std::string;
+using ushort3 = blender::vec_base<uint16_t, 3>;
+using short3 = blender::vec_base<int16_t, 3>;
+
+enum {
+  PBVH_CO_TYPE = CD_NUMTYPES,
+  PBVH_NO_TYPE = CD_NUMTYPES + 1,
+  PBVH_FSET_TYPE = CD_NUMTYPES + 2,
+  PBVH_MASK_TYPE = CD_NUMTYPES + 3
+};
+
+struct PBVHVbo {
+  uint64_t type;
+  eAttrDomain domain;
+  string name;
+  GPUVertBuf *vert_buf = nullptr;
+  string key;
+
+  PBVHVbo(eAttrDomain _domain, uint64_t _type, string _name)
+      : type(_type), domain(_domain), name(_name)
+  {
+  }
+
+  PBVHVbo(const PBVHVbo &b)
+  {
+    type = b.type;
+    domain = b.domain;
+    name = b.name;
+    vert_buf = b.vert_buf;
+    key = b.key;
+  }
+
+  string build_key()
+  {
+    char buf[512];
+
+    sprintf(buf, "%d:%d:%s", (int)type, (int)domain, name.c_str());
+
+    key = string(buf);
+    return key;
+  }
+};
+
+struct PBVHBatch {
+  Vector<PBVHVbo> vbos;
+  string key;
+  GPUBatch *tris, *lines;
+
+  void sort_vbos()
+  {
+    struct cmp {
+      bool operator()(const PBVHVbo &a, const PBVHVbo &b)
+      {
+        return a.key < b.key;
+      }
+    };
+
+    std::sort(vbos.begin(), vbos.end(), cmp());
+  }
+
+  string build_key()
+  {
+    key = "";
+
+    sort_vbos();
+
+    for (PBVHVbo &vbo : vbos) {
+      key += vbo.build_key() + ":";
+    }
+
+    return key;
+  }
+};
+
+struct PBVHBatches {
+  Vector<PBVHVbo> vbos;
+  Map<string, PBVHBatch> batches;
+  GPUIndexBuf *index_buf = nullptr;
+
+  ~PBVHBatches()
+  {
+    for (PBVHBatch &batch : batches.values()) {
+      GPU_BATCH_DISCARD_SAFE(batch.tris);
+      GPU_BATCH_DISCARD_SAFE(batch.lines);
+    }
+
+    for (PBVHVbo &vbo : vbos) {
+      GPU_vertbuf_discard(vbo.vert_buf);
+    }
+  }
+
+  string build_key(PBVHAttrReq *attrs, int attrs_num)
+  {
+    string key;
+    PBVHBatch batch;
+
+    for (int i : IndexRange(attrs_num)) {
+      PBVHAttrReq *attr = attrs + i;
+
+      PBVHVbo vbo(attr->domain, attr->type, string(attr->name));
+      vbo.build_key();
+
+      batch.vbos.append(vbo);
+    }
+
+    batch.build_key();
+    return batch.key;
+  }
+
+  bool has_vbo(eAttrDomain domain, int type, string name)
+  {
+    for (PBVHVbo &vbo : vbos) {
+      if (vbo.domain == domain && vbo.type == type && vbo.name == name) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  PBVHVbo &get_vbo(eAttrDomain domain, int type, string name)
+  {
+    for (PBVHVbo &vbo : vbos) {
+      if (vbo.domain == domain && vbo.type == type && vbo.name == name) {
+        return vbo;
+      }
+    }
+  }
+
+  bool has_batch(PBVHAttrReq *attrs, int attrs_num)
+  {
+    return batches.contains(build_key(attrs, attrs_num));
+  }
+
+  void update_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args)
+  {
+    if (!has_batch(attrs, attrs_num)) {
+      create_batch(attrs, attrs_num, args);
+    }
+  }
+
+  void fill_vbo_faces(PBVHVbo &vbo, PBVH_GPU_Args *args)
+  {
+    auto foreach =
+        [&](std::function<void(int buffer_i, int tri_i, int vertex_i, MLoopTri *tri)> func) {
+          int buffer_i = 0;
+          MLoop *mloop = args->me->mloop;
+
+          for (int i : IndexRange(args->totprim)) {
+            MLoopTri *tri = args->mlooptri + args->prim_indicies[i];
+
+            for (int j : IndexRange(3)) {
+              func(buffer_i, j, mloop[tri->tri[j]].v, tri);
+              buffer_i++;
+            }
+          }
+        };
+
+    if (GPU_vertbuf_get_data(vbo.vert_buf) == NULL ||
+        GPU_vertbuf_get_vertex_len(vbo.vert_buf) != args->node_verts_num) {
+      /* Allocate buffer if not allocated yet or size changed. */
+      GPU_vertbuf_data_alloc(vbo.vert_buf, args->node_verts_num);
+    }
+
+    void *gpu_data = GPU_vertbuf_get_data(vbo.vert_buf);
+
+    if (vbo.type == PBVH_CO_TYPE) {
+      float3 *data 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list