targets/pipe-loader: drop unused authentication
[mesa.git] / src / gallium / state_trackers / gbm / gbm_drm.c
1 /*
2 * Copyright © 2011 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Benjamin Franzke <benjaminfranzke@googlemail.com>
26 */
27
28 #include "util/u_memory.h"
29 #include "util/u_inlines.h"
30
31 #include "pipe-loader/pipe_loader.h"
32 #include "state_tracker/drm_driver.h"
33
34 #include <unistd.h>
35 #include <sys/types.h>
36
37 #include "gbm_gallium_drmint.h"
38
39 /* For importing wl_buffer */
40 #if HAVE_WAYLAND_PLATFORM
41 #include "../../../egl/wayland/wayland-drm/wayland-drm.h"
42 #endif
43
44 static INLINE enum pipe_format
45 gbm_format_to_gallium(enum gbm_bo_format format)
46 {
47 switch (format) {
48 case GBM_BO_FORMAT_XRGB8888:
49 return PIPE_FORMAT_BGRX8888_UNORM;
50 case GBM_BO_FORMAT_ARGB8888:
51 return PIPE_FORMAT_BGRA8888_UNORM;
52 default:
53 return PIPE_FORMAT_NONE;
54 }
55
56 return PIPE_FORMAT_NONE;
57 }
58
59 static INLINE uint
60 gbm_usage_to_gallium(uint usage)
61 {
62 uint resource_usage = 0;
63
64 if (usage & GBM_BO_USE_SCANOUT)
65 resource_usage |= PIPE_BIND_SCANOUT;
66
67 if (usage & GBM_BO_USE_RENDERING)
68 resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
69
70 if (usage & GBM_BO_USE_CURSOR)
71 resource_usage |= PIPE_BIND_CURSOR;
72
73 return resource_usage;
74 }
75
76 static int
77 gbm_gallium_drm_is_format_supported(struct gbm_device *gbm,
78 enum gbm_bo_format format,
79 uint32_t usage)
80 {
81 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
82 enum pipe_format pf;
83
84 pf = gbm_format_to_gallium(format);
85 if (pf == PIPE_FORMAT_NONE)
86 return 0;
87
88 if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0,
89 gbm_usage_to_gallium(usage)))
90 return 0;
91
92 if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888)
93 return 0;
94
95 return 1;
96 }
97
98 static void
99 gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo)
100 {
101 struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo);
102
103 pipe_resource_reference(&bo->resource, NULL);
104 free(bo);
105 }
106
107 static struct gbm_bo *
108 gbm_gallium_drm_bo_import(struct gbm_device *gbm,
109 uint32_t type, void *buffer, uint32_t usage)
110 {
111 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
112 struct gbm_gallium_drm_bo *bo;
113 struct winsys_handle whandle;
114 struct pipe_resource *resource;
115
116 switch (type) {
117 #if HAVE_WAYLAND_PLATFORM
118 case GBM_BO_IMPORT_WL_BUFFER:
119 {
120 struct wl_drm_buffer *wb = (struct wl_drm_buffer *) buffer;
121
122 resource = wb->driver_buffer;
123 break;
124 }
125 #endif
126
127 case GBM_BO_IMPORT_EGL_IMAGE:
128 if (!gdrm->lookup_egl_image)
129 return NULL;
130
131 resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data, buffer);
132 if (resource == NULL)
133 return NULL;
134 break;
135
136 default:
137 return NULL;
138 }
139
140 bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
141 if (bo == NULL)
142 return NULL;
143
144 bo->base.base.gbm = gbm;
145 bo->base.base.width = resource->width0;
146 bo->base.base.height = resource->height0;
147
148 switch (resource->format) {
149 case PIPE_FORMAT_BGRX8888_UNORM:
150 bo->base.base.format = GBM_BO_FORMAT_XRGB8888;
151 break;
152 case PIPE_FORMAT_BGRA8888_UNORM:
153 bo->base.base.format = GBM_BO_FORMAT_ARGB8888;
154 break;
155 default:
156 FREE(bo);
157 return NULL;
158 }
159
160 pipe_resource_reference(&bo->resource, resource);
161
162 memset(&whandle, 0, sizeof(whandle));
163 whandle.type = DRM_API_HANDLE_TYPE_KMS;
164 gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
165
166 bo->base.base.handle.u32 = whandle.handle;
167 bo->base.base.stride = whandle.stride;
168
169 return &bo->base.base;
170 }
171
172 static struct gbm_bo *
173 gbm_gallium_drm_bo_create(struct gbm_device *gbm,
174 uint32_t width, uint32_t height,
175 enum gbm_bo_format format, uint32_t usage)
176 {
177 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
178 struct gbm_gallium_drm_bo *bo;
179 struct pipe_resource templ;
180 struct winsys_handle whandle;
181 enum pipe_format pf;
182
183 bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
184 if (bo == NULL)
185 return NULL;
186
187 bo->base.base.gbm = gbm;
188 bo->base.base.width = width;
189 bo->base.base.height = height;
190 bo->base.base.format = format;
191
192 pf = gbm_format_to_gallium(format);
193 if (pf == PIPE_FORMAT_NONE)
194 return NULL;
195
196 memset(&templ, 0, sizeof(templ));
197 templ.bind = gbm_usage_to_gallium(usage);
198 templ.format = pf;
199 templ.target = PIPE_TEXTURE_2D;
200 templ.last_level = 0;
201 templ.width0 = width;
202 templ.height0 = height;
203 templ.depth0 = 1;
204 templ.array_size = 1;
205
206 bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ);
207 if (bo->resource == NULL) {
208 FREE(bo);
209 return NULL;
210 }
211
212 memset(&whandle, 0, sizeof(whandle));
213 whandle.type = DRM_API_HANDLE_TYPE_KMS;
214 gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
215
216 bo->base.base.handle.u32 = whandle.handle;
217 bo->base.base.stride = whandle.stride;
218
219 return &bo->base.base;
220 }
221
222 static void
223 gbm_gallium_drm_destroy(struct gbm_device *gbm)
224 {
225 struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
226
227 free(gdrm->base.driver_name);
228 gdrm->screen->destroy(gdrm->screen);
229 #if !GALLIUM_STATIC_TARGETS
230 pipe_loader_release(&gdrm->dev, 1);
231 #endif
232 free(gdrm);
233 }
234
235 #if !GALLIUM_STATIC_TARGETS
236 #ifdef HAVE_PIPE_LOADER_DRM
237 static const char *
238 get_library_search_path(void)
239 {
240 const char *search_path = NULL;
241
242 /* don't allow setuid apps to use GBM_BACKENDS_PATH */
243 if (geteuid() == getuid())
244 search_path = getenv("GBM_BACKENDS_PATH");
245 if (search_path == NULL)
246 search_path = PIPE_SEARCH_DIR;
247
248 return search_path;
249 }
250 #endif
251 #endif
252
253 static struct gbm_device *
254 gbm_gallium_drm_device_create(int fd)
255 {
256 struct gbm_gallium_drm_device *gdrm;
257
258 gdrm = calloc(1, sizeof *gdrm);
259 if (!gdrm)
260 return NULL;
261
262 gdrm->base.base.fd = fd;
263 gdrm->base.base.bo_create = gbm_gallium_drm_bo_create;
264 gdrm->base.base.bo_import = gbm_gallium_drm_bo_import;
265 gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy;
266 gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported;
267 gdrm->base.base.destroy = gbm_gallium_drm_destroy;
268
269 gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM;
270 gdrm->base.base.name = "drm";
271
272 #if GALLIUM_STATIC_TARGETS
273 gdrm->screen = dd_create_screen(gdrm->base.base.fd);
274 #else
275 #ifdef HAVE_PIPE_LOADER_DRM
276 if (pipe_loader_drm_probe_fd(&gdrm->dev, gdrm->base.base.fd, false))
277 gdrm->screen = pipe_loader_create_screen(gdrm->dev,
278 get_library_search_path());
279 #endif /* HAVE_PIPE_LOADER_DRM */
280 #endif
281
282 if (gdrm->screen == NULL)
283 goto out_no_screen;
284
285 #if GALLIUM_STATIC_TARGETS
286 gdrm->base.driver_name = strdup(dd_driver_name());
287 #else
288 #ifdef HAVE_PIPE_LOADER_DRM
289 gdrm->base.driver_name = strdup(gdrm->dev->driver_name);
290 #endif /* HAVE_PIPE_LOADER_DRM */
291 #endif
292 return &gdrm->base.base;
293
294 out_no_screen:
295 debug_printf("failed to load gallium_gbm\n");
296 #if !GALLIUM_STATIC_TARGETS
297 if (gdrm->dev)
298 pipe_loader_release(&gdrm->dev, 1);
299 #endif
300 free(gdrm);
301 return NULL;
302 }
303
304
305 GBM_EXPORT struct gbm_backend gbm_backend = {
306 .backend_name = "gallium_drm",
307 .create_device = gbm_gallium_drm_device_create,
308 };