[Bf-blender-cvs] [2411027] master: Multires sculpting drawing optimization:

Antony Riakiotakis noreply at git.blender.org
Mon Aug 3 19:09:39 CEST 2015


Commit: 2411027a7996170188c49e4eac0a6762f3a2599f
Author: Antony Riakiotakis
Date:   Mon Aug 3 19:08:50 2015 +0200
Branches: master
https://developer.blender.org/rB2411027a7996170188c49e4eac0a6762f3a2599f

Multires sculpting drawing optimization:

Use OpenGL 3.2 extension ARB_draw_elements_base_vertex, which allows us
to add offset in index buffer indices automatically. This should reduce
the number of draw calls significantly.

We may have some errors on the Mac with VBO setting off.
OSX OpenGL extensions don't play well with vertex arrays.
Will test that more later.

We might also use a full element buffer here, like we do when hiding
some quads, but this approach keeps the memory savings intended
originally.

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

M	source/blender/gpu/intern/gpu_buffers.c

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

diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 16dfa18..997f294 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1121,6 +1121,9 @@ struct GPU_PBVH_Buffers {
 	GPUBuffer *vert_buf, *index_buf, *index_buf_fast;
 	GLenum index_type;
 
+	int *baseelemarray;
+	void **baseindex;
+
 	/* mesh pointers in case buffer allocation fails */
 	const MPoly *mpoly;
 	const MLoop *mloop;
@@ -1681,6 +1684,18 @@ GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
 	if (buffers->index_buf)
 		buffers->vert_buf = GPU_buffer_alloc(sizeof(VertexBufferFormat) * totgrid * key->grid_area, false);
 
+	if (GLEW_ARB_draw_elements_base_vertex) {
+		int i;
+		buffers->baseelemarray = MEM_mallocN(sizeof(int) * totgrid * 2, "GPU_PBVH_Buffers.baseelemarray");
+		buffers->baseindex = MEM_mallocN(sizeof(void *) * totgrid, "GPU_PBVH_Buffers.baseindex");
+		for (i = 0; i < totgrid; i++) {
+			buffers->baseelemarray[i] = buffers->tot_quad * 6;
+			buffers->baseelemarray[i + totgrid] = i * key->grid_area;
+			buffers->baseindex[i] = buffers->index_buf && !buffers->index_buf->use_vbo ?
+			                                      buffers->index_buf->pointer : NULL;
+		}
+	}
+
 	return buffers;
 }
 
@@ -2012,21 +2027,40 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
 
 		if (buffers->tot_quad) {
 			const char *offset = base;
-			int i, last = (buffers->has_hidden || do_fast) ? 1 : buffers->totgrid;
-			for (i = 0; i < last; i++) {
+			const bool drawall = !(buffers->has_hidden || do_fast);
+
+			if (GLEW_ARB_draw_elements_base_vertex && drawall) {
+
 				glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
 				                offset + offsetof(VertexBufferFormat, co));
 				glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
 				                offset + offsetof(VertexBufferFormat, no));
 				glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
 				               offset + offsetof(VertexBufferFormat, color));
-				
-				if (do_fast)
-					glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
-				else
-					glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
 
-				offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
+				glMultiDrawElementsBaseVertex(GL_TRIANGLES, buffers->baseelemarray, buffers->index_type,
+				                              (const void * const *)buffers->baseindex,
+				                              buffers->totgrid, &buffers->baseelemarray[buffers->totgrid]);
+			}
+			else {
+				int i, last = drawall ? buffers->totgrid : 1;
+
+				/* we could optimize this to one draw call, but it would need more memory */
+				for (i = 0; i < last; i++) {
+					glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
+					                offset + offsetof(VertexBufferFormat, co));
+					glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
+					                offset + offsetof(VertexBufferFormat, no));
+					glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
+					               offset + offsetof(VertexBufferFormat, color));
+
+					if (do_fast)
+						glDrawElements(GL_TRIANGLES, buffers->totgrid * 6, buffers->index_type, index_base);
+					else
+						glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, index_base);
+
+					offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
+				}
 			}
 		}
 		else if (buffers->tot_tri) {
@@ -2112,6 +2146,10 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
 			GPU_buffer_free(buffers->index_buf);
 		if (buffers->index_buf_fast)
 			GPU_buffer_free(buffers->index_buf_fast);
+		if (buffers->baseelemarray)
+			MEM_freeN(buffers->baseelemarray);
+		if (buffers->baseindex)
+			MEM_freeN(buffers->baseindex);
 
 		MEM_freeN(buffers);
 	}




More information about the Bf-blender-cvs mailing list