vbo/dlist: keep buffers used in loopback_vertex_list() mapped.

When display list loopback path is hit the major performance
drop during glCallList() happens due to constantly mapping and
unmapping the buffer.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17285>
This commit is contained in:
Paul Gofman 2022-06-27 20:39:04 -05:00 committed by Marge Bot
parent 4d44399c2e
commit e7e989f62e
4 changed files with 23 additions and 3 deletions

View file

@ -739,6 +739,11 @@ void mesa_print_display_list(GLuint list);
static void
vbo_destroy_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *node)
{
struct gl_buffer_object *bo = node->cold->VAO[0]->BufferBinding[0].BufferObj;
if (_mesa_bufferobj_mapped(bo, MAP_INTERNAL))
_mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL);
for (gl_vertex_processing_mode mode = VP_MODE_FF; mode < VP_MODE_MAX; ++mode) {
_mesa_reference_vao(ctx, &node->cold->VAO[mode], NULL);
if (node->private_refcount[mode]) {

View file

@ -94,6 +94,7 @@ struct vbo_save_vertex_list {
struct _mesa_prim *prims;
GLuint prim_count;
GLuint min_index, max_index;
GLuint bo_bytes_used;
} *cold;
};

View file

@ -846,6 +846,7 @@ compile_vertex_list(struct gl_context *ctx)
vertex_to_index ? temp_vertices_buffer : save->vertex_store->buffer_in_ram,
node->cold->ib.obj);
save->current_bo_bytes_used += total_vert_count * save->vertex_size * sizeof(fi_type);
node->cold->bo_bytes_used = save->current_bo_bytes_used;
if (vertex_to_index) {
_mesa_hash_table_destroy(vertex_to_index, _free_entry);

View file

@ -137,6 +137,7 @@ bind_vertex_list(struct gl_context *ctx,
const struct vbo_save_vertex_list *node)
{
const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
_mesa_set_draw_vao(ctx, node->cold->VAO[mode], _vbo_get_vao_filter(mode));
}
@ -146,14 +147,26 @@ loopback_vertex_list(struct gl_context *ctx,
const struct vbo_save_vertex_list *list)
{
struct gl_buffer_object *bo = list->cold->VAO[0]->BufferBinding[0].BufferObj;
void *buffer = _mesa_bufferobj_map_range(ctx, 0, bo->Size, GL_MAP_READ_BIT, /* ? */
bo, MAP_INTERNAL);
void *buffer = NULL;
/* Reuse BO mapping when possible to avoid costly mapping on every glCallList(). */
if (_mesa_bufferobj_mapped(bo, MAP_INTERNAL)) {
if (list->cold->bo_bytes_used <= bo->Mappings[MAP_INTERNAL].Length)
buffer = bo->Mappings[MAP_INTERNAL].Pointer;
else
_mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL);
}
if (!buffer && list->cold->bo_bytes_used)
buffer = _mesa_bufferobj_map_range(ctx, 0, list->cold->bo_bytes_used, GL_MAP_READ_BIT,
bo, MAP_INTERNAL);
/* TODO: in this case, we shouldn't create a bo at all and instead keep
* the in-RAM buffer. */
_vbo_loopback_vertex_list(ctx, list, buffer);
_mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL);
if (!ctx->Const.AllowMappedBuffersDuringExecution && buffer)
_mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL);
}