From e1488d937430ac35e1e2fd0f4aa5bdbaddaa32f9 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 9 Mar 2022 13:14:38 -0800 Subject: [PATCH] radeon: Support shared memory user pointers. The RADEON_GEM_USERPTR_ANONONLY flag is hardcoded here which excludes shared memory pages. DRM is actually capable of supporting shared file- backed memory, but only if it's read-only. This mutability intent has to be conveyed through the stack, so a flags argument is added to the winsys regime to pass RADEON_FLAG_READ_ONLY. Part-of: --- src/gallium/drivers/r600/r600_buffer_common.c | 3 ++- src/gallium/drivers/radeonsi/si_buffer.c | 2 +- src/gallium/include/winsys/radeon_winsys.h | 2 +- src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 3 ++- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 15 +++++++++++---- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/r600/r600_buffer_common.c b/src/gallium/drivers/r600/r600_buffer_common.c index d1e48c1..f490dbf 100644 --- a/src/gallium/drivers/r600/r600_buffer_common.c +++ b/src/gallium/drivers/r600/r600_buffer_common.c @@ -656,7 +656,8 @@ r600_buffer_from_user_memory(struct pipe_screen *screen, util_range_add(&rbuffer->b.b, &rbuffer->b.valid_buffer_range, 0, templ->width0); /* Convert a user pointer to a buffer. */ - rbuffer->buf = ws->buffer_from_ptr(ws, user_memory, templ->width0); + rbuffer->buf = ws->buffer_from_ptr(ws, user_memory, templ->width0, + templ->usage == PIPE_USAGE_IMMUTABLE? RADEON_FLAG_READ_ONLY : 0); if (!rbuffer->buf) { FREE(rbuffer); return NULL; diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c index b468a29..756dc2e 100644 --- a/src/gallium/drivers/radeonsi/si_buffer.c +++ b/src/gallium/drivers/radeonsi/si_buffer.c @@ -650,7 +650,7 @@ static struct pipe_resource *si_buffer_from_user_memory(struct pipe_screen *scre buf->b.buffer_id_unique = util_idalloc_mt_alloc(&sscreen->buffer_ids); /* Convert a user pointer to a buffer. */ - buf->buf = ws->buffer_from_ptr(ws, user_memory, templ->width0); + buf->buf = ws->buffer_from_ptr(ws, user_memory, templ->width0, 0); if (!buf->buf) { si_resource_destroy(screen, &buf->b.b); return NULL; diff --git a/src/gallium/include/winsys/radeon_winsys.h b/src/gallium/include/winsys/radeon_winsys.h index 2c9169d..3f6eeb0 100644 --- a/src/gallium/include/winsys/radeon_winsys.h +++ b/src/gallium/include/winsys/radeon_winsys.h @@ -388,7 +388,7 @@ struct radeon_winsys { * \param pointer User pointer to turn into a buffer object. * \param Size Size in bytes for the new buffer. */ - struct pb_buffer *(*buffer_from_ptr)(struct radeon_winsys *ws, void *pointer, uint64_t size); + struct pb_buffer *(*buffer_from_ptr)(struct radeon_winsys *ws, void *pointer, uint64_t size, enum radeon_bo_flag flags); /** * Whether the buffer was created from a user pointer. diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index 22d8fd0..d9d3dac 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -1660,7 +1660,8 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, } static struct pb_buffer *amdgpu_bo_from_ptr(struct radeon_winsys *rws, - void *pointer, uint64_t size) + void *pointer, uint64_t size, + enum radeon_bo_flag flags) { struct amdgpu_winsys *ws = amdgpu_winsys(rws); amdgpu_bo_handle buf_handle; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index f4e49b8..630abcd 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -1089,7 +1089,8 @@ radeon_winsys_bo_create(struct radeon_winsys *rws, } static struct pb_buffer *radeon_winsys_bo_from_ptr(struct radeon_winsys *rws, - void *pointer, uint64_t size) + void *pointer, uint64_t size, + enum radeon_bo_flag flags) { struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); struct drm_radeon_gem_userptr args; @@ -1103,9 +1104,15 @@ static struct pb_buffer *radeon_winsys_bo_from_ptr(struct radeon_winsys *rws, memset(&args, 0, sizeof(args)); args.addr = (uintptr_t)pointer; args.size = align(size, ws->info.gart_page_size); - args.flags = RADEON_GEM_USERPTR_ANONONLY | - RADEON_GEM_USERPTR_VALIDATE | - RADEON_GEM_USERPTR_REGISTER; + + if (flags & RADEON_FLAG_READ_ONLY) + args.flags = RADEON_GEM_USERPTR_READONLY | + RADEON_GEM_USERPTR_VALIDATE; + else + args.flags = RADEON_GEM_USERPTR_ANONONLY | + RADEON_GEM_USERPTR_REGISTER | + RADEON_GEM_USERPTR_VALIDATE; + if (drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR, &args, sizeof(args))) { FREE(bo); -- 2.7.4