1*54e60f84SAndroid Build Coastguard Worker /*
2*54e60f84SAndroid Build Coastguard Worker * Copyright © 2022 Collabora Ltd.
3*54e60f84SAndroid Build Coastguard Worker * Copyright (c) 2023 Emil Velikov
4*54e60f84SAndroid Build Coastguard Worker *
5*54e60f84SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*54e60f84SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Soft-
7*54e60f84SAndroid Build Coastguard Worker * ware"), to deal in the Software without restriction, including without
8*54e60f84SAndroid Build Coastguard Worker * limitation the rights to use, copy, modify, merge, publish, distribute,
9*54e60f84SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*54e60f84SAndroid Build Coastguard Worker * Software is furnished to do so, provided that the above copyright
11*54e60f84SAndroid Build Coastguard Worker * notice(s) and this permission notice appear in all copies of the Soft-
12*54e60f84SAndroid Build Coastguard Worker * ware and that both the above copyright notice(s) and this permission
13*54e60f84SAndroid Build Coastguard Worker * notice appear in supporting documentation.
14*54e60f84SAndroid Build Coastguard Worker *
15*54e60f84SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*54e60f84SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17*54e60f84SAndroid Build Coastguard Worker * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
18*54e60f84SAndroid Build Coastguard Worker * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
19*54e60f84SAndroid Build Coastguard Worker * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
20*54e60f84SAndroid Build Coastguard Worker * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21*54e60f84SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22*54e60f84SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
23*54e60f84SAndroid Build Coastguard Worker * MANCE OF THIS SOFTWARE.
24*54e60f84SAndroid Build Coastguard Worker *
25*54e60f84SAndroid Build Coastguard Worker * Except as contained in this notice, the name of a copyright holder shall
26*54e60f84SAndroid Build Coastguard Worker * not be used in advertising or otherwise to promote the sale, use or
27*54e60f84SAndroid Build Coastguard Worker * other dealings in this Software without prior written authorization of
28*54e60f84SAndroid Build Coastguard Worker * the copyright holder.
29*54e60f84SAndroid Build Coastguard Worker *
30*54e60f84SAndroid Build Coastguard Worker * Authors:
31*54e60f84SAndroid Build Coastguard Worker * Emil Velikov ([email protected])
32*54e60f84SAndroid Build Coastguard Worker */
33*54e60f84SAndroid Build Coastguard Worker
34*54e60f84SAndroid Build Coastguard Worker #include "sysdeps.h"
35*54e60f84SAndroid Build Coastguard Worker #include <fcntl.h>
36*54e60f84SAndroid Build Coastguard Worker #include <stdlib.h>
37*54e60f84SAndroid Build Coastguard Worker #include <unistd.h>
38*54e60f84SAndroid Build Coastguard Worker #include <string.h>
39*54e60f84SAndroid Build Coastguard Worker
40*54e60f84SAndroid Build Coastguard Worker #include <xcb/xcb.h>
41*54e60f84SAndroid Build Coastguard Worker #include <xcb/dri3.h>
42*54e60f84SAndroid Build Coastguard Worker
43*54e60f84SAndroid Build Coastguard Worker #include <X11/Xlib-xcb.h>
44*54e60f84SAndroid Build Coastguard Worker #include <xf86drm.h>
45*54e60f84SAndroid Build Coastguard Worker
46*54e60f84SAndroid Build Coastguard Worker #include "va_backend.h"
47*54e60f84SAndroid Build Coastguard Worker #include "va_drmcommon.h"
48*54e60f84SAndroid Build Coastguard Worker #include "drm/va_drm_utils.h"
49*54e60f84SAndroid Build Coastguard Worker
50*54e60f84SAndroid Build Coastguard Worker static xcb_screen_t *
va_DRI3GetXCBScreen(xcb_connection_t * conn,int screen)51*54e60f84SAndroid Build Coastguard Worker va_DRI3GetXCBScreen(xcb_connection_t *conn, int screen)
52*54e60f84SAndroid Build Coastguard Worker {
53*54e60f84SAndroid Build Coastguard Worker xcb_screen_iterator_t iter;
54*54e60f84SAndroid Build Coastguard Worker
55*54e60f84SAndroid Build Coastguard Worker iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
56*54e60f84SAndroid Build Coastguard Worker for (; iter.rem; --screen, xcb_screen_next(&iter))
57*54e60f84SAndroid Build Coastguard Worker if (screen == 0)
58*54e60f84SAndroid Build Coastguard Worker return iter.data;
59*54e60f84SAndroid Build Coastguard Worker return NULL;
60*54e60f84SAndroid Build Coastguard Worker }
61*54e60f84SAndroid Build Coastguard Worker
62*54e60f84SAndroid Build Coastguard Worker static int
va_isDRI3Connected(VADriverContextP ctx,int * outfd)63*54e60f84SAndroid Build Coastguard Worker va_isDRI3Connected(VADriverContextP ctx, int *outfd)
64*54e60f84SAndroid Build Coastguard Worker {
65*54e60f84SAndroid Build Coastguard Worker xcb_connection_t *conn = XGetXCBConnection(ctx->native_dpy);
66*54e60f84SAndroid Build Coastguard Worker xcb_screen_t *screen;
67*54e60f84SAndroid Build Coastguard Worker xcb_window_t root;
68*54e60f84SAndroid Build Coastguard Worker const xcb_query_extension_reply_t *ext;
69*54e60f84SAndroid Build Coastguard Worker xcb_dri3_open_cookie_t cookie;
70*54e60f84SAndroid Build Coastguard Worker xcb_dri3_open_reply_t *reply;
71*54e60f84SAndroid Build Coastguard Worker int fd;
72*54e60f84SAndroid Build Coastguard Worker char *render_node;
73*54e60f84SAndroid Build Coastguard Worker
74*54e60f84SAndroid Build Coastguard Worker if (!conn)
75*54e60f84SAndroid Build Coastguard Worker return -1;
76*54e60f84SAndroid Build Coastguard Worker
77*54e60f84SAndroid Build Coastguard Worker screen = va_DRI3GetXCBScreen(conn, ctx->x11_screen);
78*54e60f84SAndroid Build Coastguard Worker if (!screen)
79*54e60f84SAndroid Build Coastguard Worker return -1;
80*54e60f84SAndroid Build Coastguard Worker
81*54e60f84SAndroid Build Coastguard Worker root = screen->root;
82*54e60f84SAndroid Build Coastguard Worker
83*54e60f84SAndroid Build Coastguard Worker xcb_prefetch_extension_data(conn, &xcb_dri3_id);
84*54e60f84SAndroid Build Coastguard Worker ext = xcb_get_extension_data(conn, &xcb_dri3_id);
85*54e60f84SAndroid Build Coastguard Worker if (!ext || !ext->present)
86*54e60f84SAndroid Build Coastguard Worker return -1;
87*54e60f84SAndroid Build Coastguard Worker
88*54e60f84SAndroid Build Coastguard Worker /* We don't require any of the ancy stuff, so there's no point in checking
89*54e60f84SAndroid Build Coastguard Worker * the version.
90*54e60f84SAndroid Build Coastguard Worker */
91*54e60f84SAndroid Build Coastguard Worker
92*54e60f84SAndroid Build Coastguard Worker cookie = xcb_dri3_open(conn, root, 0 /* provider */);
93*54e60f84SAndroid Build Coastguard Worker reply = xcb_dri3_open_reply(conn, cookie, NULL /* error */);
94*54e60f84SAndroid Build Coastguard Worker
95*54e60f84SAndroid Build Coastguard Worker if (!reply || reply->nfd != 1) {
96*54e60f84SAndroid Build Coastguard Worker free(reply);
97*54e60f84SAndroid Build Coastguard Worker return -1;
98*54e60f84SAndroid Build Coastguard Worker }
99*54e60f84SAndroid Build Coastguard Worker
100*54e60f84SAndroid Build Coastguard Worker fd = xcb_dri3_open_reply_fds(conn, reply)[0];
101*54e60f84SAndroid Build Coastguard Worker free(reply);
102*54e60f84SAndroid Build Coastguard Worker
103*54e60f84SAndroid Build Coastguard Worker /* The server can give us primary or a render node.
104*54e60f84SAndroid Build Coastguard Worker * In case of the former we need to swap it for the latter.
105*54e60f84SAndroid Build Coastguard Worker */
106*54e60f84SAndroid Build Coastguard Worker switch (drmGetNodeTypeFromFd(fd)) {
107*54e60f84SAndroid Build Coastguard Worker case DRM_NODE_PRIMARY:
108*54e60f84SAndroid Build Coastguard Worker render_node = drmGetRenderDeviceNameFromFd(fd);
109*54e60f84SAndroid Build Coastguard Worker close(fd);
110*54e60f84SAndroid Build Coastguard Worker if (!render_node)
111*54e60f84SAndroid Build Coastguard Worker return -1;
112*54e60f84SAndroid Build Coastguard Worker
113*54e60f84SAndroid Build Coastguard Worker fd = open(render_node, O_RDWR | O_CLOEXEC);
114*54e60f84SAndroid Build Coastguard Worker free(render_node);
115*54e60f84SAndroid Build Coastguard Worker if (fd == -1)
116*54e60f84SAndroid Build Coastguard Worker return -1;
117*54e60f84SAndroid Build Coastguard Worker
118*54e60f84SAndroid Build Coastguard Worker break;
119*54e60f84SAndroid Build Coastguard Worker case DRM_NODE_RENDER:
120*54e60f84SAndroid Build Coastguard Worker fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
121*54e60f84SAndroid Build Coastguard Worker break;
122*54e60f84SAndroid Build Coastguard Worker default:
123*54e60f84SAndroid Build Coastguard Worker close(fd);
124*54e60f84SAndroid Build Coastguard Worker return -1;
125*54e60f84SAndroid Build Coastguard Worker }
126*54e60f84SAndroid Build Coastguard Worker
127*54e60f84SAndroid Build Coastguard Worker *outfd = fd;
128*54e60f84SAndroid Build Coastguard Worker return 0;
129*54e60f84SAndroid Build Coastguard Worker }
130*54e60f84SAndroid Build Coastguard Worker
va_DRI3_GetDriverNames(VADisplayContextP pDisplayContext,char ** drivers,unsigned * num_drivers)131*54e60f84SAndroid Build Coastguard Worker VAStatus va_DRI3_GetDriverNames(
132*54e60f84SAndroid Build Coastguard Worker VADisplayContextP pDisplayContext,
133*54e60f84SAndroid Build Coastguard Worker char **drivers,
134*54e60f84SAndroid Build Coastguard Worker unsigned *num_drivers
135*54e60f84SAndroid Build Coastguard Worker )
136*54e60f84SAndroid Build Coastguard Worker {
137*54e60f84SAndroid Build Coastguard Worker VADriverContextP const ctx = pDisplayContext->pDriverContext;
138*54e60f84SAndroid Build Coastguard Worker struct drm_state * const drm_state = ctx->drm_state;
139*54e60f84SAndroid Build Coastguard Worker int fd = -1;
140*54e60f84SAndroid Build Coastguard Worker
141*54e60f84SAndroid Build Coastguard Worker if (va_isDRI3Connected(ctx, &fd) && fd != -1)
142*54e60f84SAndroid Build Coastguard Worker return VA_STATUS_ERROR_UNKNOWN;
143*54e60f84SAndroid Build Coastguard Worker
144*54e60f84SAndroid Build Coastguard Worker drm_state->fd = fd;
145*54e60f84SAndroid Build Coastguard Worker drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
146*54e60f84SAndroid Build Coastguard Worker return VA_DRM_GetDriverNames(ctx, drivers, num_drivers);
147*54e60f84SAndroid Build Coastguard Worker }
148