[Bf-blender-cvs] [fcd7de83865] tmp-batch-cache-cleanup: Mesh Batch Cache: Refactor part 4

Clément Foucault noreply at git.blender.org
Mon Jul 22 12:52:57 CEST 2019


Commit: fcd7de83865d22c1ebc72b7872e9eb120928d115
Author: Clément Foucault
Date:   Mon Jul 15 23:46:43 2019 +0200
Branches: tmp-batch-cache-cleanup
https://developer.blender.org/rBfcd7de83865d22c1ebc72b7872e9eb120928d115

Mesh Batch Cache: Refactor part 4

- Add edge factor support (with less hack + multithread support)
- Add Facedots pos/nor/flag support
- Add Loop normal support

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

M	source/blender/draw/intern/draw_cache_impl_mesh.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 620955fdffc..0bebbdd4ede 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -359,6 +359,8 @@ typedef enum eMRDataType {
   MR_DATATYPE_LOOSE_VERT = 1 << 10,
   MR_DATATYPE_LOOSE_EDGE = 1 << 11,
   MR_DATATYPE_LOOP_NORMALS = 1 << 12,
+  /* New data types to replace all above */
+  MR_DATA_POLY_NOR = 1 << 13,
 } eMRDataType;
 
 #define MR_DATATYPE_VERT_LOOP_POLY (MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP)
@@ -1260,7 +1262,8 @@ static MeshRenderData *mesh_render_data_create_ex(Mesh *me,
 
 static MeshRenderData *mesh_render_data_create_ex_new(Mesh *me,
                                                       const bool do_final,
-                                                      const int types,
+                                                      const eMRIterType types,
+                                                      const eMRDataType data_flag,
                                                       const DRW_MeshCDMask *UNUSED(cd_used),
                                                       const ToolSettings *ts)
 {
@@ -1329,6 +1332,18 @@ static MeshRenderData *mesh_render_data_create_ex_new(Mesh *me,
     mr->mloop = CustomData_get_layer(&mr->me->ldata, CD_MLOOP);
     mr->mpoly = CustomData_get_layer(&mr->me->pdata, CD_MPOLY);
 
+    if (data_flag & MR_DATA_POLY_NOR) {
+      mr->poly_normals = MEM_mallocN(sizeof(*mr->poly_normals) * mr->poly_len, __func__);
+      BKE_mesh_calc_normals_poly(mr->mvert,
+                                 NULL,
+                                 mr->vert_len,
+                                 mr->mloop,
+                                 mr->mpoly,
+                                 mr->loop_len,
+                                 mr->poly_len,
+                                 mr->poly_normals,
+                                 true);
+    }
     if (types & MR_ITER_LOOPTRI) {
       mr->mlooptri = MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI");
       BKE_mesh_recalc_looptri(mr->me->mloop,
@@ -1386,6 +1401,9 @@ static MeshRenderData *mesh_render_data_create_ex_new(Mesh *me,
     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. */
+    }
     if (types & MR_ITER_LOOPTRI) {
       /* Edit mode ensures this is valid, no need to calculate. */
       BLI_assert((bm->totloop == 0) || (mr->edit_bmesh->looptris != NULL));
@@ -2221,8 +2239,10 @@ typedef struct MeshBufferCache {
     GPUVertBuf *stretch_area;
     GPUVertBuf *stretch_angle;
     GPUVertBuf *mesh_analysis;
-    GPUVertBuf *facedots_pos_nor_data;
+    GPUVertBuf *facedots_pos;
+    GPUVertBuf *facedots_nor;
     GPUVertBuf *facedots_uv;
+    GPUVertBuf *facedots_data; /* inside facedots_nor for now. */
     GPUVertBuf *facedots_data_edituv;
     /* Selection */
     GPUVertBuf *vert_idx; /* extend */
@@ -2473,7 +2493,7 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, int mode)
       FOREACH_MESH_BUFFER_CACHE(cache, mbufcache)
       {
         GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.data);
-        GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.facedots_pos_nor_data);
+        GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.facedots_nor);
       }
       GPU_BATCH_DISCARD_SAFE(cache->batch.edit_triangles);
       GPU_BATCH_DISCARD_SAFE(cache->batch.edit_vertices);
@@ -4693,7 +4713,7 @@ typedef struct MeshExtract {
   MeshExtractIterFn *iter, *iter_edit;
   MeshExtractFinishFn *finish;
   eMRIterType iter_flag;
-  int mesh_render_flag;
+  eMRDataType data_flag;
 } MeshExtract;
 
 /** \} */
@@ -4897,6 +4917,48 @@ MeshExtract extract_points = {mesh_vert_init,
 
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract Facedots Indices
+ * \{ */
+
+static void *mesh_facedot_init(const MeshRenderData *mr, void *UNUSED(buf))
+{
+  GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__);
+  GPU_indexbuf_init(elb, GPU_PRIM_POINTS, mr->vert_len, mr->loop_len + mr->loop_loose_len);
+  /* Set all indices to primitive restart. We do this to bypass hidden elements. */
+  /* NOTE: This is not the best method as it leave holes in the index buffer.
+   * TODO: Better approach would be to remove the holes by moving all the indices block to
+   * have a continuous buffer. */
+  memset(elb->data, 0xFF, sizeof(uint) * mr->vert_len);
+  return elb;
+}
+static void mesh_facedot_iter(const MeshExtractIterData *iter, void *UNUSED(buf), void *elb)
+{
+  if (!(iter->use_hide && (iter->mpoly->flag & ME_HIDE))) {
+    GPU_indexbuf_set_point_vert(elb, iter->face_idx, iter->face_idx);
+  }
+}
+static void mesh_facedot_iter_edit(const MeshExtractIterData *iter, void *UNUSED(buf), void *elb)
+{
+  if (iter->efa && !BM_elem_flag_test(iter->efa, BM_ELEM_HIDDEN)) {
+    GPU_indexbuf_set_point_vert(elb, iter->face_idx, iter->face_idx);
+  }
+}
+static void mesh_facedot_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb)
+{
+  GPU_indexbuf_build_in_place(elb, ibo);
+  MEM_freeN(elb);
+}
+
+MeshExtract extract_facedots = {mesh_facedot_init,
+                                mesh_facedot_iter,
+                                mesh_facedot_iter_edit,
+                                mesh_facedot_finish,
+                                MR_ITER_LOOP,
+                                0};
+
+/** \} */
+
 /* ---------------------------------------------------------------------- */
 /** \name Extract Position and Vertex Normal
  * \{ */
@@ -4955,48 +5017,218 @@ MeshExtract extract_pos_nor = {mesh_pos_nor_init,
 
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract Loop Normal
+ * \{ */
+
+static void *mesh_lnor_init(const MeshRenderData *mr, void *buf)
+{
+  static GPUVertFormat format = {0};
+  if (format.attr_len == 0) {
+    GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+  }
+  GPUVertBuf *vbo = buf;
+  GPU_vertbuf_init_with_format(vbo, &format);
+  GPU_vertbuf_data_alloc(vbo, mr->loop_len);
+
+  float(*lnors)[3] = (float(*)[3])vbo->data;
+
+  const bool is_auto_smooth = (mr->me->flag & ME_AUTOSMOOTH) != 0;
+  const float split_angle = is_auto_smooth ? mr->me->smoothresh : (float)M_PI;
+
+  if (mr->iter == MR_EXTRACT_BMESH) {
+    int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL);
+    BM_loops_calc_normal_vcos(mr->bm,
+                              NULL,
+                              NULL,
+                              NULL,
+                              is_auto_smooth,
+                              split_angle,
+                              lnors,
+                              NULL,
+                              NULL,
+                              clnors_offset,
+                              false);
+  }
+  else {
+    short(*clnors)[2] = CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL);
+    BKE_mesh_normals_loop_split(mr->mvert,
+                                mr->vert_len,
+                                mr->medge,
+                                mr->edge_len,
+                                mr->mloop,
+                                lnors,
+                                mr->loop_len,
+                                mr->mpoly,
+                                mr->poly_normals,
+                                mr->poly_len,
+                                is_auto_smooth,
+                                split_angle,
+                                NULL,
+                                clnors,
+                                NULL);
+  }
+
+#if 1
+  /* Compress normal data in place. We reinit the vbo with another format.
+   * HACK we steal the buffer ownership to avoid freeing memory. */
+  static GPUVertFormat format_compressed = {0};
+  if (format_compressed.attr_len == 0) {
+    GPU_vertformat_attr_add(
+        &format_compressed, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+  }
+  /* This is to pass the mapped buffer ownership */
+  uint32_t vbo_id = vbo->vbo_id;
+  uchar *data = vbo->data;
+  /* Avoid freeing memory. */
+  vbo->vbo_id = 0;
+  vbo->data = 0;
+  GPU_vertbuf_clear(vbo);
+  GPU_vertbuf_init_with_format(vbo, &format_compressed);
+  /* NOTE: We don't alloc and reuse previous memory block. */
+  vbo->vbo_id = vbo_id;
+  vbo->data = data;
+  vbo->dirty = true;
+  /* New data is 1/3 of the size. */
+  vbo->vertex_alloc = mr->loop_len * 3;
+  vbo->vertex_len = mr->loop_len;
+  /* Compress in place. */
+  GPUPackedNormal *lnors_packed = (GPUPackedNormal *)data;
+  for (int l = 0; l < mr->loop_len; l++) {
+    lnors_packed[l] = GPU_normal_convert_i10_v3(lnors[l]);
+  }
+#endif
+  return NULL;
+}
+
+MeshExtract extract_lnor = {mesh_lnor_init, NULL, NULL, NULL, 0, MR_DATA_POLY_NOR};
+
+/** \} */
+
 /* ---------------------------------------------------------------------- */
 /** \name Extract Position and Vertex Normal
  * \{ */
 
+typedef struct MeshExtract_EdgeFac_Data {
+  uchar *vbo_data;
+  bool use_edge_render;
+  /* Number of loop per edge. */
+  uint32_t edge_loop_count[0];
+} MeshExtract_EdgeFac_Data;
+
 static void *mesh_edge_fac_init(const MeshRenderData *mr, void *buf)
 {
   static GPUVertFormat format = {0};
   if (format.attr_len == 0) {
-    if (!GPU_crappy_amd_driver()) {
-      /* Some AMD drivers strangely crash with a vbo with this format. */
-      GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
-    }
-    else {
-      /* TODO */
-      // GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
-      // data.f = 1.0f;
-      BLI_assert(0);
-    }
+    GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
   }
   GPUVertBuf *vbo = buf;
   GPU_vertbuf_init_with_format(vbo, &format);
   GPU_vertbuf_data_alloc(vbo, mr->loop_len + mr->loop_loose_len);
-  memset(vbo->data, 0xFF, sizeof(char) * (mr->loop_len + mr->loop_loose_len));
-  return vbo->data;
+
+  MeshExtract_EdgeFac_Data *data;
+
+  if (mr->iter == MR_EXTRACT_MESH) 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list