xref: /aosp_15_r20/external/libva/va/drm/va_drm_utils.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
1*54e60f84SAndroid Build Coastguard Worker /*
2*54e60f84SAndroid Build Coastguard Worker  * va_drm_utils.c - VA/DRM Utilities
3*54e60f84SAndroid Build Coastguard Worker  *
4*54e60f84SAndroid Build Coastguard Worker  * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
5*54e60f84SAndroid Build Coastguard Worker  * Copyright (c) 2023 Emil Velikov
6*54e60f84SAndroid Build Coastguard Worker  *
7*54e60f84SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*54e60f84SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
9*54e60f84SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
10*54e60f84SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
11*54e60f84SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
12*54e60f84SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
13*54e60f84SAndroid Build Coastguard Worker  * the following conditions:
14*54e60f84SAndroid Build Coastguard Worker  *
15*54e60f84SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
16*54e60f84SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
17*54e60f84SAndroid Build Coastguard Worker  * of the Software.
18*54e60f84SAndroid Build Coastguard Worker  *
19*54e60f84SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*54e60f84SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*54e60f84SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*54e60f84SAndroid Build Coastguard Worker  * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
23*54e60f84SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*54e60f84SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*54e60f84SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*54e60f84SAndroid Build Coastguard Worker  */
27*54e60f84SAndroid Build Coastguard Worker 
28*54e60f84SAndroid Build Coastguard Worker #include "sysdeps.h"
29*54e60f84SAndroid Build Coastguard Worker #include <xf86drm.h>
30*54e60f84SAndroid Build Coastguard Worker #include <sys/stat.h>
31*54e60f84SAndroid Build Coastguard Worker #include <sys/utsname.h>
32*54e60f84SAndroid Build Coastguard Worker #include "va_drm_utils.h"
33*54e60f84SAndroid Build Coastguard Worker #include "va_drmcommon.h"
34*54e60f84SAndroid Build Coastguard Worker 
35*54e60f84SAndroid Build Coastguard Worker #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
36*54e60f84SAndroid Build Coastguard Worker 
37*54e60f84SAndroid Build Coastguard Worker static char *
va_DRM_GetDrmDriverName(int fd)38*54e60f84SAndroid Build Coastguard Worker va_DRM_GetDrmDriverName(int fd)
39*54e60f84SAndroid Build Coastguard Worker {
40*54e60f84SAndroid Build Coastguard Worker     drmVersionPtr drm_version = drmGetVersion(fd);
41*54e60f84SAndroid Build Coastguard Worker     char *driver_name;
42*54e60f84SAndroid Build Coastguard Worker 
43*54e60f84SAndroid Build Coastguard Worker     if (!drm_version)
44*54e60f84SAndroid Build Coastguard Worker         return NULL;
45*54e60f84SAndroid Build Coastguard Worker 
46*54e60f84SAndroid Build Coastguard Worker     driver_name = strdup(drm_version->name);
47*54e60f84SAndroid Build Coastguard Worker     drmFreeVersion(drm_version);
48*54e60f84SAndroid Build Coastguard Worker 
49*54e60f84SAndroid Build Coastguard Worker     return driver_name;
50*54e60f84SAndroid Build Coastguard Worker }
51*54e60f84SAndroid Build Coastguard Worker 
52*54e60f84SAndroid Build Coastguard Worker /* Returns the VA driver names and how many they are, for the active display */
53*54e60f84SAndroid Build Coastguard Worker VAStatus
VA_DRM_GetDriverNames(VADriverContextP ctx,char ** drivers,unsigned * num_drivers)54*54e60f84SAndroid Build Coastguard Worker VA_DRM_GetDriverNames(VADriverContextP ctx, char **drivers, unsigned *num_drivers)
55*54e60f84SAndroid Build Coastguard Worker {
56*54e60f84SAndroid Build Coastguard Worker #define MAX_NAMES 2 // Adjust if needed
57*54e60f84SAndroid Build Coastguard Worker 
58*54e60f84SAndroid Build Coastguard Worker     static const struct {
59*54e60f84SAndroid Build Coastguard Worker         const char * const drm_driver;
60*54e60f84SAndroid Build Coastguard Worker         const char * const va_driver[MAX_NAMES];
61*54e60f84SAndroid Build Coastguard Worker     } map[] = {
62*54e60f84SAndroid Build Coastguard Worker         { "xe",         { "iHD"              } },
63*54e60f84SAndroid Build Coastguard Worker         { "i915",       { "iHD", "i965"      } }, // Intel Media and OTC GenX
64*54e60f84SAndroid Build Coastguard Worker         { "pvrsrvkm",   { "pvr"              } }, // Intel UMG PVR
65*54e60f84SAndroid Build Coastguard Worker         { "radeon",     { "r600", "radeonsi" } }, // Mesa Gallium
66*54e60f84SAndroid Build Coastguard Worker         { "amdgpu",     { "radeonsi"         } }, // Mesa Gallium
67*54e60f84SAndroid Build Coastguard Worker         { "WSL",        { "d3d12"            } }, // Mesa Gallium
68*54e60f84SAndroid Build Coastguard Worker         { "nvidia-drm", { "nvidia"           } }, // Unofficial NVIDIA
69*54e60f84SAndroid Build Coastguard Worker     };
70*54e60f84SAndroid Build Coastguard Worker 
71*54e60f84SAndroid Build Coastguard Worker     const struct drm_state * const drm_state = ctx->drm_state;
72*54e60f84SAndroid Build Coastguard Worker     char *drm_driver;
73*54e60f84SAndroid Build Coastguard Worker     unsigned count = 0;
74*54e60f84SAndroid Build Coastguard Worker 
75*54e60f84SAndroid Build Coastguard Worker     if (!drm_state || drm_state->fd < 0)
76*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_INVALID_DISPLAY;
77*54e60f84SAndroid Build Coastguard Worker 
78*54e60f84SAndroid Build Coastguard Worker     drm_driver = va_DRM_GetDrmDriverName(drm_state->fd);
79*54e60f84SAndroid Build Coastguard Worker     if (!drm_driver)
80*54e60f84SAndroid Build Coastguard Worker         return VA_STATUS_ERROR_UNKNOWN;
81*54e60f84SAndroid Build Coastguard Worker 
82*54e60f84SAndroid Build Coastguard Worker     /* Map vgem to WSL2 for Windows subsystem for linux */
83*54e60f84SAndroid Build Coastguard Worker     struct utsname sysinfo = {};
84*54e60f84SAndroid Build Coastguard Worker     if (!strncmp(drm_driver, "vgem", 4) && uname(&sysinfo) >= 0 &&
85*54e60f84SAndroid Build Coastguard Worker         strstr(sysinfo.release, "WSL")) {
86*54e60f84SAndroid Build Coastguard Worker         free(drm_driver);
87*54e60f84SAndroid Build Coastguard Worker         drm_driver = strdup("WSL");
88*54e60f84SAndroid Build Coastguard Worker         if (!drm_driver)
89*54e60f84SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNKNOWN;
90*54e60f84SAndroid Build Coastguard Worker     }
91*54e60f84SAndroid Build Coastguard Worker 
92*54e60f84SAndroid Build Coastguard Worker     for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
93*54e60f84SAndroid Build Coastguard Worker         if (strcmp(map[i].drm_driver, drm_driver) == 0) {
94*54e60f84SAndroid Build Coastguard Worker             const char * const *va_drivers = map[i].va_driver;
95*54e60f84SAndroid Build Coastguard Worker             for (; count < MAX_NAMES && va_drivers[count] && count < *num_drivers; count++)
96*54e60f84SAndroid Build Coastguard Worker                 drivers[count] = strdup(va_drivers[count]);
97*54e60f84SAndroid Build Coastguard Worker 
98*54e60f84SAndroid Build Coastguard Worker             break;
99*54e60f84SAndroid Build Coastguard Worker         }
100*54e60f84SAndroid Build Coastguard Worker     }
101*54e60f84SAndroid Build Coastguard Worker 
102*54e60f84SAndroid Build Coastguard Worker     /* Fallback to the drm driver, if there's no va equivalent in the map. */
103*54e60f84SAndroid Build Coastguard Worker     if (!count) {
104*54e60f84SAndroid Build Coastguard Worker         drivers[count] = drm_driver;
105*54e60f84SAndroid Build Coastguard Worker         count++;
106*54e60f84SAndroid Build Coastguard Worker     } else {
107*54e60f84SAndroid Build Coastguard Worker         free(drm_driver);
108*54e60f84SAndroid Build Coastguard Worker     }
109*54e60f84SAndroid Build Coastguard Worker 
110*54e60f84SAndroid Build Coastguard Worker     *num_drivers = count;
111*54e60f84SAndroid Build Coastguard Worker 
112*54e60f84SAndroid Build Coastguard Worker     return VA_STATUS_SUCCESS;
113*54e60f84SAndroid Build Coastguard Worker }
114