[Bf-blender-cvs] [2edc5b8] temp_display_optimization: Use shorts for uploading normals to GPU instead of floats.

Antony Riakiotakis noreply at git.blender.org
Wed Jul 1 12:16:19 CEST 2015


Commit: 2edc5b807bf7bcb72a63d241c095f632653fd171
Author: Antony Riakiotakis
Date:   Wed Jul 1 12:16:03 2015 +0200
Branches: temp_display_optimization
https://developer.blender.org/rB2edc5b807bf7bcb72a63d241c095f632653fd171

Use shorts for uploading normals to GPU instead of floats.

The range of shorts is acceptable for good looking
normals.

We allocate a buffer with 4 shorts to keep data aligned to 32bit
boundaries. The total mesh cost for full triangle meshes is now
equal to master branch even with index buffers and memory gains
are even more for ngons.

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

M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 4397c51..cfc7a4d 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1392,12 +1392,13 @@ static void cdDM_buffer_copy_vertex(DerivedMesh *dm, float *varray, int *UNUSED(
 	}
 }
 
-static void cdDM_buffer_copy_normal(DerivedMesh *dm, float *varray, int *UNUSED(mat_orig_to_new), void *UNUSED(user))
+static void cdDM_buffer_copy_normal(DerivedMesh *dm, float *varray_, int *UNUSED(mat_orig_to_new), void *UNUSED(user))
 {
 	int i, totface;
 	int start;
 	float f_no[3];
 
+	short *varray = (short *)varray_;
 	const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
 	short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
 	MVert *mvert = dm->getVertArray(dm);
@@ -1411,38 +1412,38 @@ static void cdDM_buffer_copy_normal(DerivedMesh *dm, float *varray, int *UNUSED(
 		if (tlnors) {
 			short (*tlnor)[3] = tlnors[i];
 			/* Copy loop normals */
-			normal_short_to_float_v3(&varray[start], tlnor[0]);
-			normal_short_to_float_v3(&varray[start + 3], tlnor[1]);
-			normal_short_to_float_v3(&varray[start + 6], tlnor[2]);
+			copy_v3_v3_short(&varray[start], tlnor[0]);
+			copy_v3_v3_short(&varray[start + 3], tlnor[1]);
+			copy_v3_v3_short(&varray[start + 6], tlnor[2]);
 			start += 9;
 
 			if (f->v4) {
-				normal_short_to_float_v3(&varray[start], tlnor[3]);
+				copy_v3_v3_short(&varray[start], tlnor[3]);
 				start += 3;
 			}
 		}
 		else if (smoothnormal) {
 			/* copy vertex normal */
-			normal_short_to_float_v3(&varray[start], mvert[f->v1].no);
-			normal_short_to_float_v3(&varray[start + 3], mvert[f->v2].no);
-			normal_short_to_float_v3(&varray[start + 6], mvert[f->v3].no);
-			start += 9;
+			copy_v3_v3_short(&varray[start], mvert[f->v1].no);
+			copy_v3_v3_short(&varray[start + 4], mvert[f->v2].no);
+			copy_v3_v3_short(&varray[start + 8], mvert[f->v3].no);
+			start += 12;
 
 			if (f->v4) {
-				normal_short_to_float_v3(&varray[start], mvert[f->v4].no);
-				start += 3;
+				copy_v3_v3_short(&varray[start], mvert[f->v4].no);
+				start += 4;
 			}
 		}
 		else if (nors) {
 			/* copy cached face normal */
-			copy_v3_v3(&varray[start], &nors[i * 3]);
-			copy_v3_v3(&varray[start + 3], &nors[i * 3]);
-			copy_v3_v3(&varray[start + 6], &nors[i * 3]);
-			start += 9;
+			normal_float_to_short_v3(&varray[start], &nors[i * 3]);
+			normal_float_to_short_v3(&varray[start + 4], &nors[i * 3]);
+			normal_float_to_short_v3(&varray[start + 8], &nors[i * 3]);
+			start += 12;
 
 			if (f->v4) {
-				copy_v3_v3(&varray[start], &nors[i * 3]);
-				start += 3;
+				normal_float_to_short_v3(&varray[start], &nors[i * 3]);
+				start += 4;
 			}
 		}
 		else {
@@ -1452,14 +1453,14 @@ static void cdDM_buffer_copy_normal(DerivedMesh *dm, float *varray, int *UNUSED(
 			else
 				normal_tri_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co);
 
-			copy_v3_v3(&varray[start], f_no);
-			copy_v3_v3(&varray[start + 3], f_no);
-			copy_v3_v3(&varray[start + 6], f_no);
-			start += 9;
+			normal_float_to_short_v3(&varray[start], f_no);
+			normal_float_to_short_v3(&varray[start + 4], f_no);
+			normal_float_to_short_v3(&varray[start + 8], f_no);
+			start += 12;
 
 			if (f->v4) {
-				copy_v3_v3(&varray[start], f_no);
-				start += 3;
+				normal_float_to_short_v3(&varray[start], f_no);
+				start += 4;
 			}
 		}
 	}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index efe11ac..b5e80df 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1763,12 +1763,13 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
 }
 
 /* Only used by non-editmesh types */
-static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray,
+static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray_,
                                     int *UNUSED(mat_orig_to_new), void *UNUSED(user_data))
 {
 	CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
 	CCGSubSurf *ss = ccgdm->ss;
 	CCGKey key;
+	short *varray = (short *)varray_;
 	short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
 	int gridSize = ccgSubSurf_getGridSize(ss);
 	int gridFaces = gridSize - 1;
@@ -1805,12 +1806,12 @@ static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray,
 				/* Can't use quad strips here... */
 				for (y = 0; y < gridFaces; y ++) {
 					for (x = 0; x < gridFaces; x ++) {
-						normal_short_to_float_v3(&varray[start], ln[0][0]);
-						normal_short_to_float_v3(&varray[start + 3], ln[0][3]);
-						normal_short_to_float_v3(&varray[start + 6], ln[0][2]);
-						normal_short_to_float_v3(&varray[start + 9], ln[0][1]);
+						copy_v3_v3_short(&varray[start], ln[0][0]);
+						copy_v3_v3_short(&varray[start + 4], ln[0][3]);
+						copy_v3_v3_short(&varray[start + 8], ln[0][2]);
+						copy_v3_v3_short(&varray[start + 12], ln[0][1]);
 
-						start += 12;
+						start += 16;
 						ln ++;
 					}
 				}
@@ -1823,12 +1824,12 @@ static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray,
 						float *c = CCG_grid_elem_no(&key, faceGridData, x + 1, y + 1);
 						float *d = CCG_grid_elem_no(&key, faceGridData, x, y + 1);
 
-						copy_v3_v3(&varray[start], a);
-						copy_v3_v3(&varray[start + 3], b);
-						copy_v3_v3(&varray[start + 6], c);
-						copy_v3_v3(&varray[start + 9], d);
+						normal_float_to_short_v3(&varray[start], a);
+						normal_float_to_short_v3(&varray[start + 4], b);
+						normal_float_to_short_v3(&varray[start + 8], c);
+						normal_float_to_short_v3(&varray[start + 12], d);
 
-						start += 12;
+						start += 16;
 					}
 				}
 			}
@@ -1843,12 +1844,12 @@ static void ccgDM_prepare_normal_data(DerivedMesh *dm, float *varray,
 
 						ccgDM_NormalFast(a, b, c, d, no);
 	
-						copy_v3_v3(&varray[start], no);
-						copy_v3_v3(&varray[start + 3], no);
-						copy_v3_v3(&varray[start + 6], no);
-						copy_v3_v3(&varray[start + 9], no);
+						normal_float_to_short_v3(&varray[start], no);
+						normal_float_to_short_v3(&varray[start + 4], no);
+						normal_float_to_short_v3(&varray[start + 8], no);
+						normal_float_to_short_v3(&varray[start + 12], no);
 
-						start += 12;
+						start += 16;
 					}
 				}
 			}
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 4263047..d89c297 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -81,7 +81,7 @@ const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
     /* vertex */
     {GL_ARRAY_BUFFER_ARB, 3},
     /* normal */
-    {GL_ARRAY_BUFFER_ARB, 3},
+    {GL_ARRAY_BUFFER_ARB, 4}, /* we copy 3 shorts per normal but we add a fourth for alignment */
     /* mcol */
     {GL_ARRAY_BUFFER_ARB, 3},
     /* uv */
@@ -596,7 +596,7 @@ static int gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
 		case GPU_BUFFER_VERTEX:
 			return sizeof(float) * gpu_buffer_type_settings[type].num_components * (dm->drawObject->tot_triangle_point + dm->drawObject->tot_loose_point);
 		case GPU_BUFFER_NORMAL:
-			return sizeof(float) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
+			return sizeof(short) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
 		case GPU_BUFFER_COLOR:
 			return sizeof(char) * gpu_buffer_type_settings[type].num_components * dm->drawObject->tot_triangle_point;
 		case GPU_BUFFER_UV:
@@ -683,10 +683,10 @@ void GPU_normal_setup(DerivedMesh *dm)
 	glEnableClientState(GL_NORMAL_ARRAY);
 	if (dm->drawObject->normals->use_vbo) {
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id);
-		glNormalPointer(GL_FLOAT, 0, 0);
+		glNormalPointer(GL_SHORT, 4 * sizeof(short), 0);
 	}
 	else {
-		glNormalPointer(GL_FLOAT, 0, dm->drawObject->normals->pointer);
+		glNormalPointer(GL_SHORT, 4 * sizeof(short), dm->drawObject->normals->pointer);
 	}
 
 	GLStates |= GPU_BUFFER_NORMAL_STATE;




More information about the Bf-blender-cvs mailing list