1 /*
2 * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #ifdef IN_LIBVA
31 # include "va/drm/va_drm.h"
32 #else
33 # include <va/va_drm.h>
34 #endif
35 #include <xf86drm.h>
36 #include "va_display.h"
37 #include <sys/utsname.h>
38
39 static int drm_fd = -1;
40 extern const char *g_device_name;
41
42 static VADisplay
va_open_display_drm(void)43 va_open_display_drm(void)
44 {
45 VADisplay va_dpy;
46 int i;
47 drmVersionPtr version;
48 static const char *drm_device_paths[] = {
49 "/dev/dri/renderD128",
50 "/dev/dri/card0",
51 "/dev/dri/renderD129",
52 "/dev/dri/card1",
53 NULL
54 };
55
56 if (g_device_name) {
57 drm_fd = open(g_device_name, O_RDWR);
58 if (drm_fd < 0) {
59 printf("Failed to open the given device!\n");
60 exit(1);
61 return NULL;
62 }
63
64 va_dpy = vaGetDisplayDRM(drm_fd);
65 if (va_dpy)
66 return va_dpy;
67
68 printf("Failed to a DRM display for the given device\n");
69 close(drm_fd);
70 drm_fd = -1;
71 exit(1);
72 return NULL;
73 }
74
75 for (i = 0; drm_device_paths[i]; i++) {
76 drm_fd = open(drm_device_paths[i], O_RDWR);
77 if (drm_fd < 0)
78 continue;
79
80 version = drmGetVersion(drm_fd);
81 if (!version) {
82 close(drm_fd);
83 continue;
84 }
85 /* On normal Linux platforms we do not want vgem.
86 * Yet Windows subsystem for linux uses vgem,
87 * while also providing a fallback VA driver.
88 * See https://github.com/intel/libva/pull/688
89 */
90 struct utsname sysinfo = {};
91 if (!strncmp(version->name, "vgem", 4) && (uname(&sysinfo) >= 0) &&
92 !strstr(sysinfo.release, "WSL")) {
93 drmFreeVersion(version);
94 close(drm_fd);
95 continue;
96 }
97 drmFreeVersion(version);
98
99 va_dpy = vaGetDisplayDRM(drm_fd);
100 if (va_dpy)
101 return va_dpy;
102
103 close(drm_fd);
104 drm_fd = -1;
105 }
106 return NULL;
107 }
108
109 static void
va_close_display_drm(VADisplay va_dpy)110 va_close_display_drm(VADisplay va_dpy)
111 {
112 if (drm_fd < 0)
113 return;
114
115 close(drm_fd);
116 drm_fd = -1;
117 }
118
119
120 static VAStatus
va_put_surface_drm(VADisplay va_dpy,VASurfaceID surface,const VARectangle * src_rect,const VARectangle * dst_rect)121 va_put_surface_drm(
122 VADisplay va_dpy,
123 VASurfaceID surface,
124 const VARectangle *src_rect,
125 const VARectangle *dst_rect
126 )
127 {
128 return VA_STATUS_ERROR_OPERATION_FAILED;
129 }
130
131 const VADisplayHooks va_display_hooks_drm = {
132 "drm",
133 va_open_display_drm,
134 va_close_display_drm,
135 va_put_surface_drm,
136 };
137