aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2020-01-22 16:20:59 -0500
committerMarge Bot <[email protected]>2020-02-11 00:34:57 +0000
commit3e0d612f5e22fee19aff0e40814db24d63f63103 (patch)
treee24f5bd9188853e8058eb5811e9d22154496ed5d /src/mesa
parent03ded3d6ce37d3be12776bcc5dcd3c4d91f33248 (diff)
vbo: don't unmap persistent buffer mappings for glBegin/End
This significantly improves performance by lowering CPU overhead. Reviewed-by: Mathias Fröhlich <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3766>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/vbo/vbo_exec.h1
-rw-r--r--src/mesa/vbo/vbo_exec_api.c3
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c46
3 files changed, 41 insertions, 9 deletions
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);