[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