vbo/dlist: keep buffers used in loopback_vertex_list() mapped.
authorPaul Gofman <pgofman@codeweavers.com>
Tue, 28 Jun 2022 01:39:04 +0000 (20:39 -0500)
committerMarge Bot <emma+marge@anholt.net>
Fri, 23 Sep 2022 04:41:50 +0000 (04:41 +0000)
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>

src/mesa/main/dlist.c
src/mesa/vbo/vbo_save.h
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c

index 594e9c5..097645b 100644 (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]) {
index 8a513c8..78a6340 100644 (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;
 };
 
index 7d91488..50b5551 100644 (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);
index 1ded742..a95fb13 100644 (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);
 }