xref: /aosp_15_r20/external/libva/va/x11/va_dri3.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
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