Commit: 6695dd5eea421a6ae8b44986a592d9b9a8c21369
Author: Mike Erwin
Date:   Thu Apr 16 16:11:55 2015 -0400
Branches: GPU_data_request
https://developer.blender.org/rB6695dd5eea421a6ae8b44986a592d9b9a8c21369

store index buffers in VRAM

With this change, smooth solid meshes draw faster in the new viewport
than old with VBOs.

Wireframe was already faster, now it's CRAZY fast.

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

M       source/blender/editors/space_view3d/drawobject.c
M       source/blender/gpu/GPUx_element.h
M       source/blender/gpu/intern/gpux_draw.c
M       source/blender/gpu/intern/gpux_element.c
M       source/blender/gpu/intern/gpux_element_private.h

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

diff --git a/source/blender/editors/space_view3d/drawobject.c 
b/source/blender/editors/space_view3d/drawobject.c
index ea45d08..3bc717a 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -4515,6 +4515,7 @@ static bool draw_mesh_object_new_new(Scene *scene, 
ARegion *ar, View3D *v3d, Reg
 //                             glShadeModel(GL_SMOOTH);
 
                                GPUx_vertex_buffer_prime(verts);
+                               GPUx_element_list_prime(elem);
 
                                dm->gpux_batch->prim_type = GL_TRIANGLES;
                                dm->gpux_batch->buff = verts;
@@ -4535,6 +4536,7 @@ static bool draw_mesh_object_new_new(Scene *scene, 
ARegion *ar, View3D *v3d, Reg
                                }
 
                                GPUx_vertex_buffer_prime(verts);
+                               GPUx_element_list_prime(elem);
 
                                dm->gpux_batch->prim_type = GL_LINES;
                                dm->gpux_batch->buff = verts;
diff --git a/source/blender/gpu/GPUx_element.h 
b/source/blender/gpu/GPUx_element.h
index d57be96..8007dab7 100644
--- a/source/blender/gpu/GPUx_element.h
+++ b/source/blender/gpu/GPUx_element.h
@@ -21,4 +21,9 @@ void GPUx_set_triangle_vertices(ElementList*, unsigned 
prim_idx, unsigned v1, un
 
 void GPUx_optimize(ElementList*); /* optionally call this after setting all 
vertex indices */
 
+/* prime does all the setup(create VBO, send to GPU, etc.) so use_primed 
doesn't have to */
+void GPUx_element_list_prime(ElementList*);
+void GPUx_element_list_use_primed(const ElementList*);
+void GPUx_element_list_done_using(const ElementList*);
+
 #endif /* BLENDER_GL_ELEMENT_LIST */
diff --git a/source/blender/gpu/intern/gpux_draw.c 
b/source/blender/gpu/intern/gpux_draw.c
index 7d4549d..c26d146 100644
--- a/source/blender/gpu/intern/gpux_draw.c
+++ b/source/blender/gpu/intern/gpux_draw.c
@@ -32,8 +32,11 @@ void GPUx_draw_points(const VertexBuffer *vbo, const 
ElementList *el, const Poin
 #ifdef REALLY_DRAW
        GPUx_vertex_buffer_use_primed(vbo);
 
-       if (el)
-               glDrawRangeElements(GL_POINTS, min_index(el), max_index(el), 
el->prim_ct, el->index_type, el->indices);
+       if (el) {
+               GPUx_element_list_use_primed(el);
+               glDrawRangeElements(GL_POINTS, min_index(el), max_index(el), 
el->prim_ct, el->index_type, index_ptr(el));
+               GPUx_element_list_done_using(el);
+       }
        else
                glDrawArrays(GL_POINTS, 0, GPUx_vertex_ct(vbo));
 
@@ -56,8 +59,11 @@ void GPUx_draw_lines(const VertexBuffer *vbo, const 
ElementList *el, const LineD
 #ifdef REALLY_DRAW
        GPUx_vertex_buffer_use_primed(vbo);
 
-       if (el)
-               glDrawRangeElements(GL_LINES, min_index(el), max_index(el), 
el->prim_ct * 2, el->index_type, el->indices);
+       if (el) {
+               GPUx_element_list_use_primed(el);
+               glDrawRangeElements(GL_LINES, min_index(el), max_index(el), 
el->prim_ct * 2, el->index_type, index_ptr(el));
+               GPUx_element_list_done_using(el);
+       }
        else
                glDrawArrays(GL_LINES, 0, chop_to_multiple(GPUx_vertex_ct(vbo), 
2));
 
@@ -80,8 +86,11 @@ void GPUx_draw_triangles(const VertexBuffer *vbo, const 
ElementList *el, const P
 #ifdef REALLY_DRAW
        GPUx_vertex_buffer_use_primed(vbo);
 
-       if (el)
-               glDrawRangeElements(GL_TRIANGLES, min_index(el), max_index(el), 
el->prim_ct * 3, el->index_type, el->indices);
+       if (el) {
+               GPUx_element_list_use_primed(el);
+               glDrawRangeElements(GL_TRIANGLES, min_index(el), max_index(el), 
el->prim_ct * 3, el->index_type, index_ptr(el));
+               GPUx_element_list_done_using(el);
+       }
        else
                glDrawArrays(GL_TRIANGLES, 0, 
chop_to_multiple(GPUx_vertex_ct(vbo), 3));
 
@@ -122,9 +131,11 @@ void GPUx_draw_primitives(const VertexBuffer *vbo, const 
ElementList *el, const
 
 #ifdef REALLY_DRAW
        GPUx_vertex_buffer_use_primed(vbo);
+       GPUx_element_list_use_primed(el);
 
-       glDrawRangeElements(el->prim_type, min_index(el), max_index(el), 
el->prim_ct * vert_per_prim, el->index_type, el->indices);
+       glDrawRangeElements(el->prim_type, min_index(el), max_index(el), 
el->prim_ct * vert_per_prim, el->index_type, index_ptr(el));
 
+       GPUx_element_list_done_using(el);
        GPUx_vertex_buffer_done_using(vbo);
 #endif /* REALLY_DRAW */
 }
@@ -185,9 +196,12 @@ void GPUx_draw_batch(const GPUxBatch *batch)
 #ifdef REALLY_DRAW
        GPUx_vertex_buffer_use_primed(batch->buff);
 
-       if (batch->elem)
+       if (batch->elem) {
+               GPUx_element_list_use_primed(batch->elem);
                glDrawRangeElements(batch->prim_type, min_index(batch->elem), 
max_index(batch->elem),
-                                   batch->elem->prim_ct * vert_per_prim, 
batch->elem->index_type, batch->elem->indices);
+                                   batch->elem->prim_ct * vert_per_prim, 
batch->elem->index_type, index_ptr(batch->elem));
+               GPUx_element_list_done_using(batch->elem);
+       }
        else
                glDrawArrays(batch->prim_type, 0, 
chop_to_multiple(GPUx_vertex_ct(batch->buff), vert_per_prim));
 
diff --git a/source/blender/gpu/intern/gpux_element.c 
b/source/blender/gpu/intern/gpux_element.c
index a92ef94..12d2689 100644
--- a/source/blender/gpu/intern/gpux_element.c
+++ b/source/blender/gpu/intern/gpux_element.c
@@ -2,6 +2,8 @@
 #include "gpux_element_private.h"
 #include <stdlib.h>
 
+/* private functions */
+
 #ifdef TRACK_INDEX_RANGE
 static void track_index_range(ElementList *el, unsigned v)
 {
@@ -30,6 +32,20 @@ unsigned max_index(const ElementList *el)
 #endif /* TRACK_INDEX_RANGE */
 }
 
+const void *index_ptr(const ElementList *el)
+{
+#ifdef USE_ELEM_VBO
+       if (el->vbo_id) /* primed, data lives in buffer object */
+               return (const void*)0;
+       else /* data lives in client memory */
+               return el->indices;
+#else
+       return el->indices;
+#endif /* USE_ELEM_VBO */
+}
+
+/* public functions */
+
 ElementList *GPUx_element_list_create(GLenum prim_type, unsigned prim_ct, 
unsigned max_index)
 {
        ElementList *el;
@@ -80,6 +96,11 @@ ElementList *GPUx_element_list_create(GLenum prim_type, 
unsigned prim_ct, unsign
 
 void GPUx_element_list_discard(ElementList *el)
 {
+#ifdef USE_ELEM_VBO
+       if (el->vbo_id)
+               glDeleteBuffers(1, &el->vbo_id);
+#endif /* USE_ELEM_VBO */
+
        free(el->indices);
        free(el);
 }
@@ -212,3 +233,58 @@ void GPUx_optimize(ElementList *el)
 
        /* TODO: (optional) rearrange vertex attrib buffer to improve mem 
locality */
 }
+
+void GPUx_element_list_prime(ElementList *el)
+{
+#ifdef USE_ELEM_VBO
+       int prim_vertex_ct = 0, index_size = 0, total_size;
+
+#ifdef TRUST_NO_ONE
+       assert(el->vbo_id == 0);
+  #endif /* TRUST_NO_ONE */
+
+       if (el->prim_type == GL_POINTS)
+               prim_vertex_ct = 1;
+       else if (el->prim_type == GL_LINES)
+               prim_vertex_ct = 2;
+       else if (el->prim_type == GL_TRIANGLES)
+               prim_vertex_ct = 3;
+
+       if (el->index_type == GL_UNSIGNED_BYTE)
+               index_size = sizeof(GLubyte);
+       else if (el->index_type == GL_UNSIGNED_SHORT)
+               index_size = sizeof(GLushort);
+       else if (el->index_type == GL_UNSIGNED_INT)
+               index_size = sizeof(GLuint);
+
+       total_size = prim_vertex_ct * el->prim_ct * index_size;
+
+       glGenBuffers(1, &el->vbo_id);
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, el->vbo_id);
+       /* fill with delicious data & send to GPU the first time only */
+       glBufferData(GL_ELEMENT_ARRAY_BUFFER, total_size, el->indices, 
GL_STATIC_DRAW);
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#else
+       (void)el;
+#endif /* USE_ELEM_VBO */
+}
+
+void GPUx_element_list_use_primed(const ElementList *el)
+{
+#ifdef USE_ELEM_VBO
+  #ifdef TRUST_NO_ONE
+       assert(el->vbo_id);
+  #endif /* TRUST_NO_ONE */
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, el->vbo_id);
+#else
+       (void)el;
+#endif /* USE_ELEM_VBO */
+}
+
+void GPUx_element_list_done_using(const ElementList *el)
+{
+       (void)el;
+#ifdef USE_ELEM_VBO
+       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#endif /* USE_ELEM_VBO */
+}
diff --git a/source/blender/gpu/intern/gpux_element_private.h 
b/source/blender/gpu/intern/gpux_element_private.h
index cac43b8..10673fc 100644
--- a/source/blender/gpu/intern/gpux_element_private.h
+++ b/source/blender/gpu/intern/gpux_element_private.h
@@ -7,19 +7,31 @@
 /* track min & max observed index (for glDrawRangeElements) */
 #define TRACK_INDEX_RANGE
 
+/* VBOs are guaranteed for any GL >= 1.5
+* They can be turned off here (mostly for comparison). */
+#define USE_ELEM_VBO
+
 struct ElementList {
        unsigned prim_ct; 
        GLenum prim_type; /* GL_POINTS, GL_LINES, GL_TRIANGLES */
        GLenum index_type; /* GL_UNSIGNED_BYTE, _SHORT (ES), also _INT (full 
GL) */
        unsigned max_allowed_index;
+
 #ifdef TRACK_INDEX_RANGE
        unsigned min_observed_index;
        unsigned max_observed_index;
 #endif /* TRACK_INDEX_RANGE */
+
+#ifdef USE_ELEM_VBO
+       GLuint vbo_id;
+#endif /* USE_ELEM_VBO */
+
        void *indices; /* array of index_type */
 };
 
 unsigned min_index(const ElementList*);
 unsigned max_index(const ElementList*);
 
+const void *index_ptr(const ElementList*); /* for glDrawElements */
+
 #endif /* BLENDER_GL_ELEMENT_LIST_PRIVATE */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to