[Bf-blender-cvs] [fd3589e4c96] blender2.8: DwM: optimize mesh batch conversion

Campbell Barton noreply at git.blender.org
Thu Jun 29 12:14:44 CEST 2017


Commit: fd3589e4c969d2e08b864e0e60c8c25f23e50145
Author: Campbell Barton
Date:   Thu Jun 29 20:11:16 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBfd3589e4c969d2e08b864e0e60c8c25f23e50145

DwM: optimize mesh batch conversion

- Replace GWN_vertbuf_attr_set with Gwn_VertBufRaw & GWN_vertbuf_raw_step
  to avoid intermediate copy.
- Avoid extra conversion step with: float[3] -> short[3] -> Gwn_PackedNormal.
  We can skip the short[3].

Gives approx 6% speedup here.

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

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 13b94c00dc6..6c62cf3b0f6 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -190,8 +190,8 @@ typedef struct MeshRenderData {
 	float (*poly_normals)[3];
 	float (*vert_weight_color)[3];
 	char (*vert_color)[3];
-	short (*poly_normals_short)[3];
-	short (*vert_normals_short)[3];
+	Gwn_PackedNormal *poly_normals_pack;
+	Gwn_PackedNormal *vert_normals_pack;
 	bool *edge_select_bool;
 } MeshRenderData;
 
@@ -760,8 +760,8 @@ static void mesh_render_data_free(MeshRenderData *rdata)
 	MEM_SAFE_FREE(rdata->edges_adjacent_polys);
 	MEM_SAFE_FREE(rdata->mlooptri);
 	MEM_SAFE_FREE(rdata->poly_normals);
-	MEM_SAFE_FREE(rdata->poly_normals_short);
-	MEM_SAFE_FREE(rdata->vert_normals_short);
+	MEM_SAFE_FREE(rdata->poly_normals_pack);
+	MEM_SAFE_FREE(rdata->vert_normals_pack);
 	MEM_SAFE_FREE(rdata->vert_weight_color);
 	MEM_SAFE_FREE(rdata->edge_select_bool);
 	MEM_SAFE_FREE(rdata->vert_color);
@@ -870,20 +870,20 @@ static int mesh_render_data_polys_len_get(const MeshRenderData *rdata)
 /** \name Internal Cache (Lazy Initialization)
  * \{ */
 
-/** Ensure #MeshRenderData.poly_normals_short */
-static void mesh_render_data_ensure_poly_normals_short(MeshRenderData *rdata)
+/** Ensure #MeshRenderData.poly_normals_pack */
+static void mesh_render_data_ensure_poly_normals_pack(MeshRenderData *rdata)
 {
-	short (*pnors_short)[3] = rdata->poly_normals_short;
-	if (pnors_short == NULL) {
+	Gwn_PackedNormal *pnors_pack = rdata->poly_normals_pack;
+	if (pnors_pack == NULL) {
 		if (rdata->edit_bmesh) {
 			BMesh *bm = rdata->edit_bmesh->bm;
 			BMIter fiter;
 			BMFace *efa;
 			int i;
 
-			pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+			pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
 			BM_ITER_MESH_INDEX(efa, &fiter, bm, BM_FACES_OF_MESH, i) {
-				normal_float_to_short_v3(pnors_short[i], efa->no);
+				pnors_pack[i] = GWN_normal_convert_i10_v3(efa->no);
 			}
 		}
 		else {
@@ -896,28 +896,28 @@ static void mesh_render_data_ensure_poly_normals_short(MeshRenderData *rdata)
 				        rdata->mloop, rdata->mpoly, rdata->loop_len, rdata->poly_len, pnors, true);
 			}
 
-			pnors_short = rdata->poly_normals_short = MEM_mallocN(sizeof(*pnors_short) * rdata->poly_len, __func__);
+			pnors_pack = rdata->poly_normals_pack = MEM_mallocN(sizeof(*pnors_pack) * rdata->poly_len, __func__);
 			for (int i = 0; i < rdata->poly_len; i++) {
-				normal_float_to_short_v3(pnors_short[i], pnors[i]);
+				pnors_pack[i] = GWN_normal_convert_i10_v3(pnors[i]);
 			}
 		}
 	}
 }
 
-/** Ensure #MeshRenderData.vert_normals_short */
-static void mesh_render_data_ensure_vert_normals_short(MeshRenderData *rdata)
+/** Ensure #MeshRenderData.vert_normals_pack */
+static void mesh_render_data_ensure_vert_normals_pack(MeshRenderData *rdata)
 {
-	short (*vnors_short)[3] = rdata->vert_normals_short;
-	if (vnors_short == NULL) {
+	Gwn_PackedNormal *vnors_pack = rdata->vert_normals_pack;
+	if (vnors_pack == NULL) {
 		if (rdata->edit_bmesh) {
 			BMesh *bm = rdata->edit_bmesh->bm;
 			BMIter viter;
 			BMVert *eve;
 			int i;
 
-			vnors_short = rdata->vert_normals_short = MEM_mallocN(sizeof(*vnors_short) * rdata->vert_len, __func__);
+			vnors_pack = rdata->vert_normals_pack = MEM_mallocN(sizeof(*vnors_pack) * rdata->vert_len, __func__);
 			BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
-				normal_float_to_short_v3(vnors_short[i], eve->no);
+				vnors_pack[i] = GWN_normal_convert_i10_v3(eve->no);
 			}
 		}
 		else {
@@ -1268,63 +1268,6 @@ static void mesh_render_data_looptri_tans_get(
 	}
 }
 
-static bool mesh_render_data_looptri_cos_nors_smooth_get(
-        MeshRenderData *rdata, const int tri_idx, const bool use_hide,
-        float *(*r_vert_cos)[3], short **r_tri_nor, short *(*r_vert_nors)[3], bool *r_is_smooth)
-{
-	BLI_assert(rdata->types & MR_DATATYPE_VERT);
-	BLI_assert(rdata->types & MR_DATATYPE_LOOPTRI);
-	BLI_assert(rdata->types & MR_DATATYPE_LOOP);
-	BLI_assert(rdata->types & MR_DATATYPE_POLY);
-
-	if (rdata->edit_bmesh) {
-		const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
-
-		/* Assume 'use_hide' */
-		if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
-			return false;
-		}
-
-		mesh_render_data_ensure_poly_normals_short(rdata);
-		mesh_render_data_ensure_vert_normals_short(rdata);
-
-		short (*pnors_short)[3] = rdata->poly_normals_short;
-		short (*vnors_short)[3] = rdata->vert_normals_short;
-
-		(*r_vert_cos)[0] = bm_looptri[0]->v->co;
-		(*r_vert_cos)[1] = bm_looptri[1]->v->co;
-		(*r_vert_cos)[2] = bm_looptri[2]->v->co;
-		*r_tri_nor = pnors_short[BM_elem_index_get(bm_looptri[0]->f)];
-		(*r_vert_nors)[0] = vnors_short[BM_elem_index_get(bm_looptri[0]->v)];
-		(*r_vert_nors)[1] = vnors_short[BM_elem_index_get(bm_looptri[1]->v)];
-		(*r_vert_nors)[2] = vnors_short[BM_elem_index_get(bm_looptri[2]->v)];
-
-		*r_is_smooth = BM_elem_flag_test_bool(bm_looptri[0]->f, BM_ELEM_SMOOTH);
-	}
-	else {
-		const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
-
-		if (use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE)) {
-			return false;
-		}
-
-		mesh_render_data_ensure_poly_normals_short(rdata);
-
-		short (*pnors_short)[3] = rdata->poly_normals_short;
-
-		(*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co;
-		(*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co;
-		(*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co;
-		*r_tri_nor = pnors_short[mlt->poly];
-		(*r_vert_nors)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].no;
-		(*r_vert_nors)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].no;
-		(*r_vert_nors)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].no;
-
-		*r_is_smooth = (rdata->mpoly[mlt->poly].flag & ME_SMOOTH) != 0;
-	}
-	return true;
-}
-
 /* First 2 bytes are bit flags
  * 3rd is for sharp edges
  * 4rd is for creased edges */
@@ -1981,8 +1924,6 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
 	BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
 
 	if (*r_vbo == NULL) {
-		unsigned int vidx = 0, nidx = 0;
-
 		static Gwn_VertFormat format = { 0 };
 		static struct { uint pos, nor; } attr_id;
 		if (format.attrib_ct == 0) {
@@ -1998,41 +1939,90 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
 		int vbo_len_used = 0;
 		GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
 
-		for (int i = 0; i < tri_len; i++) {
-			float *tri_vert_cos[3];
-			short *tri_nor, *tri_vert_nors[3];
-			bool is_smooth;
+		Gwn_VertBufRaw pos_step, nor_step;
+		GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
+		GWN_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step);
 
-			if (mesh_render_data_looptri_cos_nors_smooth_get(
-			        rdata, i, use_hide, &tri_vert_cos, &tri_nor, &tri_vert_nors, &is_smooth))
-			{
-				if (is_smooth) {
-					Gwn_PackedNormal snor_pack[3] = {
-						GWN_normal_convert_i10_s3(tri_vert_nors[0]),
-						GWN_normal_convert_i10_s3(tri_vert_nors[1]),
-						GWN_normal_convert_i10_s3(tri_vert_nors[2])
-					};
-					Gwn_PackedNormal *snor[3] = { &snor_pack[0], &snor_pack[1], &snor_pack[2] };
-
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor[0]);
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor[1]);
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor[2]);
+		if (rdata->edit_bmesh) {
+			mesh_render_data_ensure_poly_normals_pack(rdata);
+			mesh_render_data_ensure_vert_normals_pack(rdata);
+
+			Gwn_PackedNormal *pnors_pack = rdata->poly_normals_pack;
+			Gwn_PackedNormal *vnors_pack = rdata->vert_normals_pack;
+
+			for (int i = 0; i < tri_len; i++) {
+				const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+				const BMFace *bm_face = bm_looptri[0]->f;
+
+				/* use_hide always for edit-mode */
+				if (BM_elem_flag_test(bm_face, BM_ELEM_HIDDEN)) {
+					continue;
+				}
+
+				const uint vtri[3] = {
+					BM_elem_index_get(bm_looptri[0]->v),
+					BM_elem_index_get(bm_looptri[1]->v),
+					BM_elem_index_get(bm_looptri[2]->v),
+				};
+
+				if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
+					for (uint t = 0; t < 3; t++) {
+						*((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = vnors_pack[vtri[t]];
+					}
 				}
 				else {
-					Gwn_PackedNormal snor_pack = GWN_normal_convert_i10_s3(tri_nor);
-					Gwn_PackedNormal *snor = &snor_pack;
+					const Gwn_PackedNormal *snor_pack = &pnors_pack[BM_elem_index_get(bm_face)];
+					for (uint t = 0; t < 3; t++) {
+						*((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = *snor_pack;
+					}
+				}
 
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor);
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor);
-					GWN_vertbuf_attr_set(vbo, attr_id.nor, nidx++, snor);
+				for (uint t = 0; t < 3; t++) {
+					copy_v3_v3(GWN_vertbuf_raw_step(&pos_step), bm_looptri[t]->v->co);
 				}
+			}
+		}
+		else {
+
+			/* Use normals from vertex */
+			mesh_render_data_ensure_poly_normals_pack(rdata);
 
-				GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, tri_vert_cos[0]);
-				GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, tri_vert_cos[1]);
-				GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx++, tri_vert_cos[2]);
+			for (int i = 0; i < tri_len; i++) {
+				const MLoopTri *mlt = &rdata->mlooptri[i];
+				const MPoly *mp = &rdata->mpoly[mlt->poly];
+
+				if (use_hide && (mp->flag & ME_HIDE)) {
+					continue;
+				}
+
+				const uint vtri[3] = {
+					rdata->mloop[mlt->tri[0]].v,
+					rdata->mloop[mlt->tri[1]].v,
+					rdata->mloop[mlt->tri[2]].v,
+				};
+
+				if (mp->flag & ME_SMOOTH) {
+					for (uint t = 0; t < 3; t++) {
+						const MVert *mv = &rdata->mvert[vtri[t]];
+						*((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = GWN_normal_convert_i10_s3(mv->no);
+					}
+				}
+				else {
+					const Gwn_PackedNormal *pnors_pack = &rdata->poly_normals_pack[mlt->poly];
+					for (uint t = 0; t < 3; t++) {
+						*((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = *pnors_pack;


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list