diff options
author | Brian Paul <[email protected]> | 2013-10-14 17:36:06 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2013-10-16 08:13:45 -0600 |
commit | 3c074e4d4daf8174581b83506b22ebf7dbad553f (patch) | |
tree | f0eeae34529b3b33f4f6aa1e19c9874dcc44796f /src/mesa | |
parent | fa9c702164768f6ef05bdb02deff2f49a8d166de (diff) |
vbo: access VBO memory more efficiently when building display lists
Use GL_MAP_INVALIDATE_RANGE, UNSYNCHRONIZED and FLUSH_EXPLICIT flags
when mapping VBOs during display list compilation. This mirrors what
we do for immediate-mode VBO building in vbo_exec_vtx_map().
This improves performance for applications which interleave display
list compilation with execution. For example:
glNewList(A);
glBegin/End prims;
glEndList();
glCallList(A);
glNewList(B);
glBegin/End prims;
glEndList();
glCallList(B);
Mesa's vbo module tries to combine the vertex data from lists A and B
into the same VBO when there's room. Before, when we mapped the VBO for
building list B, we did so with GL_MAP_WRITE_BIT only. Even though we
were writing to an unused part of the buffer, the map would stall until
the preceeding drawing call finished.
Use the extra map flags and FlushMappedBufferRange() to avoid the stall.
Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index b5f9517872f..411c0060480 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -237,16 +237,31 @@ GLfloat * vbo_save_map_vertex_store(struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store) { + const GLbitfield access = (GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); + assert(vertex_store->bufferobj); - assert(!vertex_store->buffer); + assert(!vertex_store->buffer); /* the buffer should not be mapped */ + if (vertex_store->bufferobj->Size > 0) { - vertex_store->buffer = - (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0, - vertex_store->bufferobj->Size, - GL_MAP_WRITE_BIT, /* not used */ - vertex_store->bufferobj); - assert(vertex_store->buffer); - return vertex_store->buffer + vertex_store->used; + /* Map the remaining free space in the VBO */ + GLintptr offset = vertex_store->used * sizeof(GLfloat); + GLsizeiptr size = vertex_store->bufferobj->Size - offset; + GLfloat *range = (GLfloat *) + ctx->Driver.MapBufferRange(ctx, offset, size, access, + vertex_store->bufferobj); + if (range) { + /* compute address of start of whole buffer (needed elsewhere) */ + vertex_store->buffer = range - vertex_store->used; + assert(vertex_store->buffer); + return range; + } + else { + vertex_store->buffer = NULL; + return NULL; + } } else { /* probably ran out of memory for buffers */ @@ -260,6 +275,14 @@ vbo_save_unmap_vertex_store(struct gl_context *ctx, struct vbo_save_vertex_store *vertex_store) { if (vertex_store->bufferobj->Size > 0) { + GLintptr offset = 0; + GLsizeiptr length = vertex_store->used * sizeof(GLfloat) + - vertex_store->bufferobj->Offset; + + /* Explicitly flush the region we wrote to */ + ctx->Driver.FlushMappedBufferRange(ctx, offset, length, + vertex_store->bufferobj); + ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj); } vertex_store->buffer = NULL; |