radeonsi: fix refcount with memobj

The existing refcounting code is correct, unless si_texture_from_winsys_buffer
fails in which case we get a refcount error.

The error code path will use si_texture_reference(&tex, NULL), which
will drop a reference to the memobj buffer, but none was taken yet.

Reviewed-by: Ganesh Belgur Ramachandra <ganesh.belgurramachandra@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36228>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2025-07-18 16:36:11 +02:00 committed by Marge Bot
parent 7ed553ba09
commit 7c2a9e8d2a
4 changed files with 21 additions and 14 deletions

View file

@ -19,7 +19,7 @@ spec@khr_texture_compression_astc@miptree-gles srgb-fp@sRGB decode full precisio
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@oes_shader_io_blocks@compiler@layout-location-aliasing.vert,Fail
spec@ext_external_objects@vk-depth-display,Crash
spec@ext_external_objects@vk-depth-display,Fail
spec@ext_external_objects@vk-depth-display@D16,Fail
spec@ext_external_objects@vk-depth-display@D32S8,Fail
spec@ext_external_objects@vk-stencil-display,Fail

1 # piglit failures
19 spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp,Fail
20 spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp@sRGB decode full precision,Fail
21 spec@oes_shader_io_blocks@compiler@layout-location-aliasing.vert,Fail
22 spec@ext_external_objects@vk-depth-display,Crash spec@ext_external_objects@vk-depth-display,Fail
23 spec@ext_external_objects@vk-depth-display@D16,Fail
24 spec@ext_external_objects@vk-depth-display@D32S8,Fail
25 spec@ext_external_objects@vk-stencil-display,Fail

View file

@ -688,7 +688,8 @@ static struct pipe_resource *si_buffer_from_user_memory(struct pipe_screen *scre
struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen,
const struct pipe_resource *templ,
struct pb_buffer_lean *imported_buf,
uint64_t offset)
uint64_t offset,
bool take_ownership)
{
if (offset + templ->width0 > imported_buf->size)
return NULL;
@ -731,7 +732,11 @@ struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen,
res->b.is_shared = true;
res->b.buffer_id_unique = util_idalloc_mt_alloc(&sscreen->buffer_ids);
res->buf = imported_buf;
if (take_ownership)
res->buf = imported_buf;
else
radeon_bo_reference(sscreen->ws, &res->buf, imported_buf);
res->gpu_address = sscreen->ws->buffer_get_virtual_address(res->buf) + offset;
res->domains = domains;
res->flags = flags;

View file

@ -1452,7 +1452,8 @@ struct si_resource *si_aligned_buffer_create(struct pipe_screen *screen, unsigne
struct pipe_resource *si_buffer_from_winsys_buffer(struct pipe_screen *screen,
const struct pipe_resource *templ,
struct pb_buffer_lean *imported_buf,
uint64_t offset);
uint64_t offset,
bool take_ownership);
void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *dst,
struct pipe_resource *src, unsigned num_rebinds,
uint32_t rebind_mask, uint32_t delete_buffer_id);

View file

@ -1719,7 +1719,8 @@ static struct pipe_resource *si_texture_from_winsys_buffer(struct si_screen *ssc
const struct pipe_resource *templ,
struct pb_buffer_lean *buf, unsigned stride,
uint64_t offset, uint64_t modifier,
unsigned usage, bool dedicated)
unsigned usage, bool dedicated,
bool take_ownership)
{
struct radeon_surf surface = {};
struct radeon_bo_metadata metadata = {};
@ -1788,6 +1789,11 @@ static struct pipe_resource *si_texture_from_winsys_buffer(struct si_screen *ssc
if (!tex)
return NULL;
if (!take_ownership) {
struct pb_buffer_lean *tmp = NULL;
radeon_bo_reference(sscreen->ws, &tmp, buf);
}
tex->buffer.b.is_shared = true;
tex->buffer.external_usage = usage;
tex->num_planes = 1;
@ -1867,7 +1873,7 @@ static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
return NULL;
if (templ->target == PIPE_BUFFER)
return si_buffer_from_winsys_buffer(screen, templ, buf, 0);
return si_buffer_from_winsys_buffer(screen, templ, buf, 0, true);
if (whandle->plane >= util_format_get_num_planes(whandle->format)) {
struct si_auxiliary_texture *tex = CALLOC_STRUCT_CL(si_auxiliary_texture);
@ -1885,7 +1891,7 @@ static struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
}
return si_texture_from_winsys_buffer(sscreen, templ, buf, whandle->stride, whandle->offset,
whandle->modifier, usage, true);
whandle->modifier, usage, true, true);
}
bool si_init_flushed_depth_texture(struct pipe_context *ctx, struct pipe_resource *texture)
@ -2386,22 +2392,17 @@ static struct pipe_resource *si_resource_from_memobj(struct pipe_screen *screen,
struct pipe_resource *res;
if (templ->target == PIPE_BUFFER)
res = si_buffer_from_winsys_buffer(screen, templ, memobj->buf, offset);
res = si_buffer_from_winsys_buffer(screen, templ, memobj->buf, offset, false);
else
res = si_texture_from_winsys_buffer(sscreen, templ, memobj->buf,
memobj->stride,
offset, DRM_FORMAT_MOD_INVALID,
PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE | PIPE_HANDLE_USAGE_SHADER_WRITE,
memobj->b.dedicated);
memobj->b.dedicated, false);
if (!res)
return NULL;
/* si_texture_from_winsys_buffer doesn't increment refcount of
* memobj->buf, so increment it here.
*/
struct pb_buffer_lean *buf = NULL;
radeon_bo_reference(sscreen->ws, &buf, memobj->buf);
return res;
}