diff options
author | Brian Paul <[email protected]> | 2013-05-03 19:00:07 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2013-05-03 19:00:07 -0600 |
commit | 4ea05bcba66cb0d49cbad20158b41864a20a73b9 (patch) | |
tree | de6816913b5064297fbd591253f61aa2da4cf8c7 /src/mesa/vbo | |
parent | 3702d2508249bb264ab502c0093dbbc10b0b02fa (diff) |
vbo: implement primitive merging for glBegin/End sequences
A surprising number of apps and benchmarks have poor code like this:
glBegin(GL_LINE_STRIP);
glVertex(v1);
glVertex(v2);
glEnd();
// Possibly some no-op state changes here
glBegin(GL_LINE_STRIP);
glVertex(v3);
glVertex(v4);
glEnd();
// repeat many, many times.
The above sequence can be converted into:
glBegin(GL_LINES);
glVertex(v1);
glVertex(v2);
glVertex(v3);
glVertex(v4);
glEnd();
Similarly for GL_POINTS, GL_TRIANGLES, etc.
Merging was already implemented for GL_QUADS in the display list code.
Now other prim types are handled and it's also done for immediate mode.
In one case:
before after
-----------------------------------------------
number of st_draw_vbo() calls: 141 45
number of _mesa_prims issued: 7520 632
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src/mesa/vbo')
-rw-r--r-- | src/mesa/vbo/vbo_exec_api.c | 30 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 22 |
2 files changed, 38 insertions, 14 deletions
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 88cce984f8d..600398c5891 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -719,6 +719,34 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) /** + * Try to merge / concatenate the two most recent VBO primitives. + */ +static void +try_vbo_merge(struct vbo_exec_context *exec) +{ + struct _mesa_prim *cur = &exec->vtx.prim[exec->vtx.prim_count - 1]; + + assert(exec->vtx.prim_count >= 1); + + vbo_try_prim_conversion(cur); + + if (exec->vtx.prim_count >= 2) { + struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2]; + assert(prev == cur - 1); + + if (vbo_can_merge_prims(prev, cur)) { + assert(cur->begin); + assert(cur->end); + assert(prev->begin); + assert(prev->end); + vbo_merge_prims(prev, cur); + exec->vtx.prim_count--; /* drop the last primitive */ + } + } +} + + +/** * Called via glEnd. */ static void GLAPIENTRY vbo_exec_End( void ) @@ -744,6 +772,8 @@ static void GLAPIENTRY vbo_exec_End( void ) exec->vtx.prim[i].end = 1; exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; + + try_vbo_merge(exec); } ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index b8dd90c67f1..04904e11969 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -305,9 +305,9 @@ _save_reset_counters(struct gl_context *ctx) * previous prim. */ static void -vbo_merge_prims(struct gl_context *ctx, - struct _mesa_prim *prim_list, - GLuint *prim_count) +merge_prims(struct gl_context *ctx, + struct _mesa_prim *prim_list, + GLuint *prim_count) { GLuint i; struct _mesa_prim *prev_prim = prim_list; @@ -315,19 +315,13 @@ vbo_merge_prims(struct gl_context *ctx, for (i = 1; i < *prim_count; i++) { struct _mesa_prim *this_prim = prim_list + i; - if (this_prim->mode == prev_prim->mode && - this_prim->mode == GL_QUADS && - this_prim->count % 4 == 0 && - prev_prim->count % 4 == 0 && - this_prim->start == prev_prim->start + prev_prim->count && - this_prim->basevertex == prev_prim->basevertex && - this_prim->num_instances == prev_prim->num_instances && - this_prim->base_instance == prev_prim->base_instance) { + vbo_try_prim_conversion(this_prim); + + if (vbo_can_merge_prims(prev_prim, this_prim)) { /* We've found a prim that just extend the previous one. Tack it * onto the previous one, and let this primitive struct get dropped. */ - prev_prim->count += this_prim->count; - prev_prim->end = this_prim->end; + vbo_merge_prims(prev_prim, this_prim); continue; } @@ -420,7 +414,7 @@ _save_compile_vertex_list(struct gl_context *ctx) */ save->copied.nr = _save_copy_vertices(ctx, node, save->buffer); - vbo_merge_prims(ctx, node->prim, &node->prim_count); + merge_prims(ctx, node->prim, &node->prim_count); /* Deal with GL_COMPILE_AND_EXECUTE: */ |