From: Michel Dänzer Date: Fri, 28 Jun 2019 16:35:56 +0000 (+0200) Subject: winsys/amdgpu: Make KMS handles valid for original DRM file descriptor X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=11a3679e3aba3524cf987f1f808d92c25f16e080;p=mesa.git winsys/amdgpu: Make KMS handles valid for original DRM file descriptor Getting a DMA-buf fd and converting that to a handle using our duplicate of that file descriptor (getting at which requires passing a radeon_winsys pointer to the buffer_get_handle hook) makes sure of this, since duplicated file descriptors reference the same file description and therefore the same GEM handle namespace. This is necessary because libdrm_amdgpu may use a different DRM file descriptor with a separate handle namespace internally, e.g. because it always reuses any existing amdgpu_device_handle for the same device. amdgpu_bo_export returns a handle which is valid for that internal file descriptor. Bugzilla: https://bugs.freedesktop.org/110903 Reviewed-by: Marek Olšák Tested-by: Pierre-Eric Pelloux-Prayer --- diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 21ade4022c5..a9dc869b87c 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -1048,7 +1048,7 @@ boolean r300_resource_get_handle(struct pipe_screen* screen, return FALSE; } - return rws->buffer_get_handle(tex->buf, tex->tex.stride_in_bytes[0], + return rws->buffer_get_handle(rws, tex->buf, tex->tex.stride_in_bytes[0], 0, 0, whandle); } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 12812e0e396..cd09debf273 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -572,8 +572,8 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen, res->external_usage = usage; } - return rscreen->ws->buffer_get_handle(res->buf, stride, offset, - slice_size, whandle); + return rscreen->ws->buffer_get_handle(rscreen->ws, res->buf, stride, + offset, slice_size, whandle); } static void r600_texture_destroy(struct pipe_screen *screen, diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index c27627e8926..525c28182ed 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -411,12 +411,14 @@ struct radeon_winsys { * Get a winsys handle from a winsys buffer. The internal structure * of the handle is platform-specific and only a winsys should access it. * + * \param ws The winsys instance for which the handle is to be valid * \param buf A winsys buffer object to get the handle from. * \param whandle A winsys handle pointer. * \param stride A stride of the buffer in bytes, for texturing. * \return true on success. */ - bool (*buffer_get_handle)(struct pb_buffer *buf, + bool (*buffer_get_handle)(struct radeon_winsys *ws, + struct pb_buffer *buf, unsigned stride, unsigned offset, unsigned slice_size, struct winsys_handle *whandle); diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index dd383635675..4f9b85cd768 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -944,8 +944,8 @@ static boolean si_texture_get_handle(struct pipe_screen* screen, res->external_usage = usage; } - return sscreen->ws->buffer_get_handle(res->buf, stride, offset, - slice_size, whandle); + return sscreen->ws->buffer_get_handle(sscreen->ws, res->buf, stride, + offset, slice_size, whandle); } static void si_texture_destroy(struct pipe_screen *screen, diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index f1a6cc41af7..7ff84cfb175 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -1524,11 +1524,13 @@ error: return NULL; } -static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, +static bool amdgpu_bo_get_handle(struct radeon_winsys *rws, + struct pb_buffer *buffer, unsigned stride, unsigned offset, unsigned slice_size, struct winsys_handle *whandle) { + struct amdgpu_screen_winsys *sws = amdgpu_screen_winsys(rws); struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(buffer); struct amdgpu_winsys *ws = bo->ws; enum amdgpu_bo_handle_type type; @@ -1544,12 +1546,10 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, case WINSYS_HANDLE_TYPE_SHARED: type = amdgpu_bo_handle_type_gem_flink_name; break; + case WINSYS_HANDLE_TYPE_KMS: case WINSYS_HANDLE_TYPE_FD: type = amdgpu_bo_handle_type_dma_buf_fd; break; - case WINSYS_HANDLE_TYPE_KMS: - type = amdgpu_bo_handle_type_kms; - break; default: return false; } @@ -1558,6 +1558,16 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, if (r) return false; + if (whandle->type == WINSYS_HANDLE_TYPE_KMS) { + int dma_fd = whandle->handle; + + r = drmPrimeFDToHandle(sws->fd, dma_fd, &whandle->handle); + close(dma_fd); + + if (r) + return false; + } + simple_mtx_lock(&ws->bo_export_table_lock); util_hash_table_set(ws->bo_export_table, bo->bo, bo); simple_mtx_unlock(&ws->bo_export_table_lock); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index d1e2a8685ba..e9e0784e9ab 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -1285,7 +1285,8 @@ fail: return NULL; } -static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer, +static bool radeon_winsys_bo_get_handle(struct radeon_winsys *rws, + struct pb_buffer *buffer, unsigned stride, unsigned offset, unsigned slice_size, struct winsys_handle *whandle)