From 90cb1493b711a7b6447d57cee38a76f58aa06ca5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 9 Dec 2021 11:58:35 +1000 Subject: [PATCH] mesa/st: start moving bufferobject alloc/free/reference to main. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This moves these out of the state tracker code Reviewed-by: Marek Olšák Part-of: --- src/mesa/main/bufferobj.c | 39 +++++++++++++++++-- src/mesa/main/bufferobj.h | 36 ++++++++++++++++++ src/mesa/main/glthread_bufferobj.c | 7 ++-- src/mesa/state_tracker/st_atom_array.cpp | 4 +- src/mesa/state_tracker/st_atom_constbuf.c | 3 +- src/mesa/state_tracker/st_cb_bufferobjects.c | 57 +--------------------------- src/mesa/state_tracker/st_cb_bufferobjects.h | 34 ----------------- src/mesa/state_tracker/st_draw.c | 2 +- src/mesa/vbo/vbo_exec_api.c | 2 +- src/mesa/vbo/vbo_save_api.c | 4 +- 10 files changed, 85 insertions(+), 103 deletions(-) diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 5a086ac..15d70b0 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -52,6 +52,7 @@ #include "state_tracker/st_cb_bufferobjects.h" +#include "util/u_inlines.h" /* Debug flags */ /*#define VBO_DEBUG*/ /*#define BOUNDS_CHECK*/ @@ -453,6 +454,26 @@ convert_clear_buffer_data(struct gl_context *ctx, } } +void +mesa_buffer_object_release_buffer(struct gl_buffer_object *obj) +{ + if (!obj->buffer) + return; + + /* Subtract the remaining private references before unreferencing + * the buffer. See the header file for explanation. + */ + if (obj->private_refcount) { + assert(obj->private_refcount > 0); + p_atomic_add(&obj->buffer->reference.count, + -obj->private_refcount); + obj->private_refcount = 0; + } + obj->private_refcount_ctx = NULL; + + pipe_resource_reference(&obj->buffer, NULL); +} + /** * Delete a buffer object. * @@ -462,7 +483,9 @@ void _mesa_delete_buffer_object(struct gl_context *ctx, struct gl_buffer_object *bufObj) { - (void) ctx; + assert(bufObj->RefCount == 0); + _mesa_buffer_unmap_all_mappings(ctx, bufObj); + mesa_buffer_object_release_buffer(bufObj); vbo_delete_minmax_cache(bufObj); align_free(bufObj->Data); @@ -501,7 +524,7 @@ _mesa_reference_buffer_object_(struct gl_context *ctx, */ if (shared_binding || ctx != oldObj->Ctx) { if (p_atomic_dec_zero(&oldObj->RefCount)) { - st_bufferobj_free(ctx, oldObj); + _mesa_delete_buffer_object(ctx, oldObj); } } else if (ctx == oldObj->Ctx) { /* Update the private ref count. */ @@ -801,6 +824,16 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); } +struct gl_buffer_object * +_mesa_internal_buffer_object_alloc(struct gl_context *ctx, GLuint id) +{ + struct gl_buffer_object *buf = CALLOC_STRUCT(gl_buffer_object); + if (!buf) + return NULL; + + _mesa_initialize_buffer_object(ctx, buf, id); + return buf; +} /** * Create a buffer object that will be backed by an OpenGL buffer ID * where the creating context will hold one global buffer reference instead @@ -811,7 +844,7 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) static struct gl_buffer_object * new_gl_buffer_object(struct gl_context *ctx, GLuint id) { - struct gl_buffer_object *buf = st_bufferobj_alloc(ctx, id); + struct gl_buffer_object *buf = _mesa_internal_buffer_object_alloc(ctx, id); buf->Ctx = ctx; buf->RefCount++; /* global buffer reference held by the context */ diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 66b954a..23d7d26 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -36,6 +36,42 @@ * Internal functions */ +static inline struct pipe_resource * +_mesa_get_buffer_object_reference(struct gl_context *ctx, struct gl_buffer_object *obj) +{ + if (unlikely(!obj)) + return NULL; + + struct pipe_resource *buffer = obj->buffer; + + if (unlikely(!buffer)) + return NULL; + + /* Only one context is using the fast path. All other contexts must use + * the slow path. + */ + if (unlikely(obj->private_refcount_ctx != ctx)) { + p_atomic_inc(&buffer->reference.count); + return buffer; + } + + if (unlikely(obj->private_refcount <= 0)) { + assert(obj->private_refcount == 0); + + /* This is the number of atomic increments we will skip. */ + obj->private_refcount = 100000000; + p_atomic_add(&buffer->reference.count, obj->private_refcount); + } + + /* Return a buffer reference while decrementing the private refcount. */ + obj->private_refcount--; + return buffer; +} + +struct gl_buffer_object * +_mesa_internal_buffer_object_alloc(struct gl_context *ctx, GLuint id); +void +mesa_buffer_object_release_buffer(struct gl_buffer_object *obj); /** Is the given buffer object currently mapped by the GL user? */ static inline GLboolean diff --git a/src/mesa/main/glthread_bufferobj.c b/src/mesa/main/glthread_bufferobj.c index 2818ee7..03879de 100644 --- a/src/mesa/main/glthread_bufferobj.c +++ b/src/mesa/main/glthread_bufferobj.c @@ -36,7 +36,8 @@ new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr) { assert(ctx->GLThread.SupportsBufferUploads); - struct gl_buffer_object *obj = st_bufferobj_alloc(ctx, -1); + struct gl_buffer_object *obj = + _mesa_internal_buffer_object_alloc(ctx, -1); if (!obj) return NULL; @@ -46,7 +47,7 @@ new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr) GL_WRITE_ONLY, GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT, obj)) { - st_bufferobj_free(ctx, obj); + _mesa_delete_buffer_object(ctx, obj); return NULL; } @@ -56,7 +57,7 @@ new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr) MESA_MAP_THREAD_SAFE_BIT, obj, MAP_GLTHREAD); if (!*ptr) { - st_bufferobj_free(ctx, obj); + _mesa_delete_buffer_object(ctx, obj); return NULL; } diff --git a/src/mesa/state_tracker/st_atom_array.cpp b/src/mesa/state_tracker/st_atom_array.cpp index ec5892e..6d06181 100644 --- a/src/mesa/state_tracker/st_atom_array.cpp +++ b/src/mesa/state_tracker/st_atom_array.cpp @@ -109,7 +109,7 @@ setup_arrays(struct st_context *st, /* Set the vertex buffer. */ if (binding->BufferObj) { vbuffer[bufidx].buffer.resource = - st_get_buffer_reference(ctx, binding->BufferObj); + _mesa_get_buffer_object_reference(ctx, binding->BufferObj); vbuffer[bufidx].is_user_buffer = false; vbuffer[bufidx].buffer_offset = binding->Offset + attrib->RelativeOffset; @@ -142,7 +142,7 @@ setup_arrays(struct st_context *st, if (binding->BufferObj) { /* Set the binding */ vbuffer[bufidx].buffer.resource = - st_get_buffer_reference(ctx, binding->BufferObj); + _mesa_get_buffer_object_reference(ctx, binding->BufferObj); vbuffer[bufidx].is_user_buffer = false; vbuffer[bufidx].buffer_offset = _mesa_draw_binding_offset(binding); } else { diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 923e67b..2542695 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -41,6 +41,7 @@ #include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" +#include "main/bufferobj.h" #include "st_debug.h" #include "st_context.h" #include "st_atom.h" @@ -272,7 +273,7 @@ st_bind_ubos(struct st_context *st, struct gl_program *prog, binding = &st->ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding]; - cb.buffer = st_get_buffer_reference(st->ctx, binding->BufferObject); + cb.buffer = _mesa_get_buffer_object_reference(st->ctx, binding->BufferObject); if (cb.buffer) { cb.buffer_offset = binding->Offset; diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 4ad4576..aa08c53 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -51,61 +51,6 @@ /** - * There is some duplication between mesa's bufferobjects and our - * bufmgr buffers. Both have an integer handle and a hashtable to - * lookup an opaque structure. It would be nice if the handles and - * internal structure where somehow shared. - */ -struct gl_buffer_object * -st_bufferobj_alloc(struct gl_context *ctx, GLuint name) -{ - struct gl_buffer_object *obj = ST_CALLOC_STRUCT(gl_buffer_object); - - if (!obj) - return NULL; - - _mesa_initialize_buffer_object(ctx, obj, name); - - return obj; -} - - -static void -release_buffer(struct gl_buffer_object *obj) -{ - if (!obj->buffer) - return; - - /* Subtract the remaining private references before unreferencing - * the buffer. See the header file for explanation. - */ - if (obj->private_refcount) { - assert(obj->private_refcount > 0); - p_atomic_add(&obj->buffer->reference.count, - -obj->private_refcount); - obj->private_refcount = 0; - } - obj->private_refcount_ctx = NULL; - - pipe_resource_reference(&obj->buffer, NULL); -} - - -/** - * Deallocate/free a vertex/pixel buffer object. - * Called via glDeleteBuffersARB(). - */ -void st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj) -{ - assert(obj->RefCount == 0); - _mesa_buffer_unmap_all_mappings(ctx, obj); - release_buffer(obj); - _mesa_delete_buffer_object(ctx, obj); -} - - - -/** * Replace data in a subrange of buffer object. If the data range * specified by size + offset extends beyond the end of the buffer or * if data is NULL, no copy is performed. @@ -343,7 +288,7 @@ bufferobj_data(struct gl_context *ctx, obj->Usage = usage; obj->StorageFlags = storageFlags; - release_buffer(obj); + mesa_buffer_object_release_buffer(obj); unsigned bindings = buffer_target_to_bind_flags(target); diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h index e37987d..004a7ee 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.h +++ b/src/mesa/state_tracker/st_cb_bufferobjects.h @@ -43,40 +43,6 @@ extern void st_init_bufferobject_functions(struct pipe_screen *screen, struct dd_function_table *functions); -static inline struct pipe_resource * -st_get_buffer_reference(struct gl_context *ctx, struct gl_buffer_object *obj) -{ - if (unlikely(!obj)) - return NULL; - - struct pipe_resource *buffer = obj->buffer; - - if (unlikely(!buffer)) - return NULL; - - /* Only one context is using the fast path. All other contexts must use - * the slow path. - */ - if (unlikely(obj->private_refcount_ctx != ctx)) { - p_atomic_inc(&buffer->reference.count); - return buffer; - } - - if (unlikely(obj->private_refcount <= 0)) { - assert(obj->private_refcount == 0); - - /* This is the number of atomic increments we will skip. */ - obj->private_refcount = 100000000; - p_atomic_add(&buffer->reference.count, obj->private_refcount); - } - - /* Return a buffer reference while decrementing the private refcount. */ - obj->private_refcount--; - return buffer; -} - -struct gl_buffer_object *st_bufferobj_alloc(struct gl_context *ctx, GLuint name); -void st_bufferobj_free(struct gl_context *ctx, struct gl_buffer_object *obj); void st_bufferobj_subdata(struct gl_context *ctx, GLintptrARB offset, GLsizeiptrARB size, diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 4a171d6..d783c30 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -154,7 +154,7 @@ prepare_indexed_draw(/* pass both st and ctx to reduce dereferences */ * the threaded batch buffer. */ info->index.resource = - st_get_buffer_reference(ctx, info->index.gl_bo); + _mesa_get_buffer_object_reference(ctx, info->index.gl_bo); info->take_index_buffer_ownership = true; } else { info->index.resource = info->index.gl_bo->buffer; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 287b9f1..871fec3 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -1097,7 +1097,7 @@ vbo_exec_vtx_init(struct vbo_exec_context *exec) { struct gl_context *ctx = gl_context_from_vbo_exec(exec); - exec->vtx.bufferobj = st_bufferobj_alloc(ctx, IMM_BUFFER_NAME); + exec->vtx.bufferobj = _mesa_internal_buffer_object_alloc(ctx, IMM_BUFFER_NAME); exec->vtx.enabled = u_bit_consecutive64(0, VBO_ATTRIB_MAX); /* reset all */ vbo_reset_all_attr(exec); diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 066c564..0a3d758 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -768,7 +768,7 @@ compile_vertex_list(struct gl_context *ctx) if (total_bytes_needed > available_bytes) { if (save->current_bo) _mesa_reference_buffer_object(ctx, &save->current_bo, NULL); - save->current_bo = st_bufferobj_alloc(ctx, VBO_BUF_ID + 1); + save->current_bo = _mesa_internal_buffer_object_alloc(ctx, VBO_BUF_ID + 1); bool success = st_bufferobj_data(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, MAX2(total_bytes_needed, VBO_SAVE_BUFFER_SIZE), @@ -901,7 +901,7 @@ end: node->draw_begins = node->cold->prims[0].begin; if (!save->current_bo) { - save->current_bo = st_bufferobj_alloc(ctx, VBO_BUF_ID + 1); + save->current_bo = _mesa_internal_buffer_object_alloc(ctx, VBO_BUF_ID + 1); bool success = st_bufferobj_data(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, VBO_SAVE_BUFFER_SIZE, -- 2.7.4