diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 594e9c551a9..097645bbdc0 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -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]) { diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 8a513c8cf7e..78a6340c196 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -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; }; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 7d914887829..50b5551f597 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -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); diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 1ded742373e..a95fb13b0ed 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -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); }