winsys/radeon: switch to rendernode when card node doesn't work

initializing the winsys from a /dev/dri/cardX node (as discovered by
gbm) doesn't work, as the kernel abi expects a render node

thus, the winsys needs to open the card's rendernode and use that
everywhere except when importing buffers, where it has to explicitly
export from the card node and import to the rendernode

Acked-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30224>
This commit is contained in:
Mike Blumenkrantz
2024-07-16 15:55:24 -04:00
committed by Marge Bot
parent 216ff9591b
commit f673e2bf68
3 changed files with 24 additions and 2 deletions

View File

@@ -1179,7 +1179,16 @@ static struct pb_buffer_lean *radeon_winsys_bo_from_handle(struct radeon_winsys
bo = util_hash_table_get(ws->bo_names, (void*)(uintptr_t)whandle->handle);
} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
/* We must first get the GEM handle, as fds are unreliable keys */
r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
if (ws->rendernode_fd != -1) {
int handle2;
r = drmPrimeHandleToFD(ws->rendernode_fd, whandle->handle, DRM_CLOEXEC, &handle2);
if (r)
goto fail;
r = drmPrimeFDToHandle(ws->fd, handle2, &handle);
close(handle2);
} else {
r = drmPrimeFDToHandle(ws->fd, whandle->handle, &handle);
}
if (r)
goto fail;
bo = util_hash_table_get(ws->bo_handles, (void*)(uintptr_t)handle);

View File

@@ -96,6 +96,14 @@ static bool radeon_get_drm_value(struct radeon_drm_winsys *ws, unsigned request,
retval = drmCommandWriteRead(radeon_drm_winsys_fd(ws), DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
/* try switching over to a render node */
if (retval == -EACCES && ws->rendernode_fd == -1) {
ws->rendernode_fd = open(drmGetRenderDeviceNameFromFd(ws->fd), O_RDWR);
if (ws->rendernode_fd != -1)
return radeon_get_drm_value(ws, request, errname, out);
}
}
if (retval && ws->rendernode_fd == -1) {
if (errname) {
fprintf(stderr, "radeon: Failed to get %s, error number %d\n",
errname, retval);
@@ -676,6 +684,8 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
if (ws->fd >= 0)
close(ws->fd);
if (ws->rendernode_fd >= 0)
close(ws->rendernode_fd);
FREE(rws);
}
@@ -883,6 +893,7 @@ radeon_drm_winsys_create(int fd, const struct pipe_screen_config *config,
}
ws->fd = os_dupfd_cloexec(fd);
ws->rendernode_fd = -1;
if (!do_winsys_init(ws))
goto fail1;
@@ -1005,6 +1016,8 @@ fail1:
radeon_surface_manager_free(ws->surf_man);
if (ws->fd >= 0)
close(ws->fd);
if (ws->rendernode_fd >= 0)
close(ws->rendernode_fd);
FREE(ws);
return NULL;

View File

@@ -93,7 +93,7 @@ static inline struct radeon_drm_winsys *radeon_drm_winsys(struct radeon_winsys *
ALWAYS_INLINE static int
radeon_drm_winsys_fd(const struct radeon_drm_winsys *ws)
{
return ws->fd;
return ws->rendernode_fd == -1 ? ws->fd : ws->rendernode_fd;
}
uint32_t radeon_drm_get_gpu_reset_counter(struct radeon_drm_winsys *ws);