From: Marek Olšák Date: Wed, 22 Jan 2020 21:20:59 +0000 (-0500) Subject: vbo: don't unmap persistent buffer mappings for glBegin/End X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e0d612f5e22fee19aff0e40814db24d63f63103;p=mesa.git vbo: don't unmap persistent buffer mappings for glBegin/End This significantly improves performance by lowering CPU overhead. Reviewed-by: Mathias Fröhlich Part-of: --- diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index 2624dcec0f2..a5f7888ad4b 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -87,6 +87,7 @@ struct vbo_exec_context fi_type *buffer_map; fi_type *buffer_ptr; /* cursor, points into buffer */ GLuint buffer_used; /* in bytes */ + unsigned buffer_offset; /* only for persistent mappings */ fi_type vertex[VBO_ATTRIB_MAX*4]; /* current vertex */ GLuint vert_count; /**< Number of vertices currently in buffer */ diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 37ce92d6041..2fac34c2073 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -448,7 +448,8 @@ vbo_exec_begin_vertices(struct gl_context *ctx) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; - vbo_exec_vtx_map(exec); + if (unlikely(!exec->vtx.buffer_ptr)) + vbo_exec_vtx_map(exec); assert((ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) == 0); assert(exec->begin_vertices_flags); diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index ce13c32f95d..f1be9942a02 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -179,7 +179,8 @@ vbo_exec_bind_arrays(struct gl_context *ctx) GLintptr buffer_offset; if (_mesa_is_bufferobj(exec->vtx.bufferobj)) { assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer); - buffer_offset = exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset; + buffer_offset = exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + + exec->vtx.buffer_offset; } else { /* Ptr into ordinary app memory */ buffer_offset = (GLbyte *)exec->vtx.buffer_map - (GLbyte *)NULL; @@ -266,6 +267,12 @@ vbo_exec_vtx_unmap(struct vbo_exec_context *exec) } } +static bool +vbo_exec_buffer_has_space(struct vbo_exec_context *exec) +{ + return VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024; +} + /** * Map the vertex buffer to begin storing glVertex, glColor, etc data. @@ -293,7 +300,7 @@ vbo_exec_vtx_map(struct vbo_exec_context *exec) assert(!exec->vtx.buffer_map); assert(!exec->vtx.buffer_ptr); - if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024) { + if (vbo_exec_buffer_has_space(exec)) { /* The VBO exists and there's room for more */ if (exec->vtx.bufferobj->Size > 0) { exec->vtx.buffer_map = (fi_type *) @@ -340,6 +347,7 @@ vbo_exec_vtx_map(struct vbo_exec_context *exec) } exec->vtx.buffer_ptr = exec->vtx.buffer_map; + exec->vtx.buffer_offset = 0; if (!exec->vtx.buffer_map) { /* out of memory */ @@ -363,11 +371,17 @@ vbo_exec_vtx_map(struct vbo_exec_context *exec) /** * Execute the buffer and save copied verts. - * \param keep_unmapped if true, leave the VBO unmapped when we're done. + * \param unmap if true, leave the VBO unmapped when we're done. */ void -vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) +vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean unmap) { + /* Only unmap if persistent mappings are unsupported. */ + bool persistent_mapping = exec->ctx->Extensions.ARB_buffer_storage && + _mesa_is_bufferobj(exec->vtx.bufferobj) && + exec->vtx.buffer_map; + unmap = unmap && !persistent_mapping; + if (0) vbo_exec_debug_verts(exec); @@ -385,7 +399,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) if (ctx->NewState) _mesa_update_state(ctx); - vbo_exec_vtx_unmap(exec); + if (!persistent_mapping) + vbo_exec_vtx_unmap(exec); assert(ctx->NewState == 0); @@ -398,18 +413,33 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) NULL, 0, NULL); /* Get new storage -- unless asked not to. */ - if (!keepUnmapped) + if (!persistent_mapping && !unmap) vbo_exec_vtx_map(exec); } } /* May have to unmap explicitly if we didn't draw: */ - if (keepUnmapped && exec->vtx.buffer_map) { + if (unmap && exec->vtx.buffer_map) { vbo_exec_vtx_unmap(exec); } - if (keepUnmapped || exec->vtx.vertex_size == 0) + if (persistent_mapping) { + exec->vtx.buffer_used += (exec->vtx.buffer_ptr - exec->vtx.buffer_map) * + sizeof(float); + exec->vtx.buffer_map = exec->vtx.buffer_ptr; + + /* Set the buffer offset for the next draw. */ + exec->vtx.buffer_offset = exec->vtx.buffer_used; + + if (!vbo_exec_buffer_has_space(exec)) { + /* This will allocate a new buffer. */ + vbo_exec_vtx_unmap(exec); + vbo_exec_vtx_map(exec); + } + } + + if (unmap || exec->vtx.vertex_size == 0) exec->vtx.max_vert = 0; else exec->vtx.max_vert = vbo_compute_max_verts(exec);