llvmpipe: Fix external memory object reference

Make the external memory object a reference counted object. Without
that deleting the memory object in OpenGL would also delete and unmap
the memfd, which causes any operation on a texture or buffer that is
bound to that memory object to access invalid memory.

Fixes: 1608a815e3 ("llvmpipe: add support for EXT_memory_object(_fd)")
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31022>
This commit is contained in:
Thomas Wagner
2024-07-01 17:55:02 +02:00
committed by Marge Bot
parent f39cd30f4f
commit af16ec6e0c
2 changed files with 20 additions and 7 deletions

View File

@@ -449,6 +449,7 @@ llvmpipe_memobj_create_from_handle(struct pipe_screen *pscreen,
{
#ifdef PIPE_MEMORY_FD
struct llvmpipe_memory_object *memobj = CALLOC_STRUCT(llvmpipe_memory_object);
pipe_reference_init(&memobj->reference, 1);
if (handle->type == WINSYS_HANDLE_TYPE_FD &&
pscreen->import_memory_fd(pscreen, handle->handle, &memobj->data, &memobj->size, false)) {
@@ -467,10 +468,13 @@ llvmpipe_memobj_destroy(struct pipe_screen *pscreen,
if (!memobj)
return;
struct llvmpipe_memory_object *lpmo = llvmpipe_memory_object(memobj);
if (pipe_reference(&lpmo->reference, NULL))
{
#ifdef PIPE_MEMORY_FD
pscreen->free_memory_fd(pscreen, lpmo->data);
pscreen->free_memory_fd(pscreen, lpmo->data);
#endif
free(lpmo);
free(lpmo);
}
}
@@ -526,7 +530,8 @@ llvmpipe_resource_from_memobj(struct pipe_screen *pscreen,
lpr->data = lpmo->data;
}
lpr->id = id_counter++;
lpr->imported_memory = true;
lpr->imported_memory = &lpmo->b;
pipe_reference(NULL, &lpmo->reference);
#if MESA_DEBUG
simple_mtx_lock(&resource_list_mutex);
@@ -556,13 +561,19 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
} else if (llvmpipe_resource_is_texture(pt)) {
/* free linear image data */
if (lpr->tex_data) {
if (!lpr->imported_memory)
if (lpr->imported_memory)
llvmpipe_memobj_destroy(pscreen, lpr->imported_memory);
else
align_free(lpr->tex_data);
lpr->tex_data = NULL;
lpr->imported_memory = NULL;
}
} else if (lpr->data) {
if (!lpr->imported_memory)
align_free(lpr->data);
if (lpr->imported_memory)
llvmpipe_memobj_destroy(pscreen, lpr->imported_memory);
else
align_free(lpr->data);
lpr->imported_memory = NULL;
}
}

View File

@@ -53,6 +53,7 @@ enum llvmpipe_memory_fd_type
struct pipe_context;
struct pipe_screen;
struct pipe_memory_object;
struct llvmpipe_context;
struct llvmpipe_screen;
@@ -113,7 +114,7 @@ struct llvmpipe_resource
struct llvmpipe_memory_allocation *dmabuf_alloc;
#endif
bool backable;
bool imported_memory;
struct pipe_memory_object *imported_memory;
bool dmabuf;
#if MESA_DEBUG
struct list_head list;
@@ -142,6 +143,7 @@ struct llvmpipe_memory_allocation
struct llvmpipe_memory_object
{
struct pipe_memory_object b;
struct pipe_reference reference;
struct pipe_memory_allocation *data;
uint64_t size;
};