Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-06-29 13:11:16 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-06-29 13:11:16 +0300
commitfd3589e4c969d2e08b864e0e60c8c25f23e50145 (patch)
tree9be9f85d2de50f32dd736ded6a6bc15cfb520f4a /source/blender/draw/intern/draw_cache_impl_mesh.c
parent34566aa96910e29eceb45d29c9d50471452f8d73 (diff)
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.
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_mesh.c')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c198
1 files changed, 94 insertions, 104 deletions
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;
+ }
+ }
+
+ for (uint t = 0; t < 3; t++) {
+ const MVert *mv = &rdata->mvert[vtri[t]];
+ copy_v3_v3(GWN_vertbuf_raw_step(&pos_step), mv->co);
+ }
}
}
- vbo_len_used = vidx;
+
+ vbo_len_used = GWN_vertbuf_raw_used(&pos_step);
+ BLI_assert(vbo_len_used == GWN_vertbuf_raw_used(&nor_step));
if (vbo_len_capacity != vbo_len_used) {
GWN_vertbuf_data_resize(vbo, vbo_len_used);