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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
};
|
||||
|
Reference in New Issue
Block a user