2 * Copyright © 2011 Intel Corporation
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:
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
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.
25 * Benjamin Franzke <benjaminfranzke@googlemail.com>
28 #include "util/u_memory.h"
29 #include "util/u_inlines.h"
31 #include "pipe-loader/pipe_loader.h"
32 #include "state_tracker/drm_driver.h"
35 #include <sys/types.h>
37 #include "gbm_gallium_drmint.h"
39 /* For importing wl_buffer */
40 #if HAVE_WAYLAND_PLATFORM
41 #include "../../../egl/wayland/wayland-drm/wayland-drm.h"
44 static INLINE
enum pipe_format
45 gbm_format_to_gallium(enum gbm_bo_format 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
;
53 return PIPE_FORMAT_NONE
;
56 return PIPE_FORMAT_NONE
;
60 gbm_usage_to_gallium(uint usage
)
62 uint resource_usage
= 0;
64 if (usage
& GBM_BO_USE_SCANOUT
)
65 resource_usage
|= PIPE_BIND_SCANOUT
;
67 if (usage
& GBM_BO_USE_RENDERING
)
68 resource_usage
|= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
70 if (usage
& GBM_BO_USE_CURSOR
)
71 resource_usage
|= PIPE_BIND_CURSOR
;
73 return resource_usage
;
77 gbm_gallium_drm_is_format_supported(struct gbm_device
*gbm
,
78 enum gbm_bo_format format
,
81 struct gbm_gallium_drm_device
*gdrm
= gbm_gallium_drm_device(gbm
);
84 pf
= gbm_format_to_gallium(format
);
85 if (pf
== PIPE_FORMAT_NONE
)
88 if (!gdrm
->screen
->is_format_supported(gdrm
->screen
, PIPE_TEXTURE_2D
, pf
, 0,
89 gbm_usage_to_gallium(usage
)))
92 if (usage
& GBM_BO_USE_SCANOUT
&& format
!= GBM_BO_FORMAT_XRGB8888
)
99 gbm_gallium_drm_bo_destroy(struct gbm_bo
*_bo
)
101 struct gbm_gallium_drm_bo
*bo
= gbm_gallium_drm_bo(_bo
);
103 pipe_resource_reference(&bo
->resource
, NULL
);
107 static struct gbm_bo
*
108 gbm_gallium_drm_bo_import(struct gbm_device
*gbm
,
109 uint32_t type
, void *buffer
, uint32_t usage
)
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
;
117 #if HAVE_WAYLAND_PLATFORM
118 case GBM_BO_IMPORT_WL_BUFFER
:
120 struct wl_drm_buffer
*wb
= (struct wl_drm_buffer
*) buffer
;
122 resource
= wb
->driver_buffer
;
127 case GBM_BO_IMPORT_EGL_IMAGE
:
128 if (!gdrm
->lookup_egl_image
)
131 resource
= gdrm
->lookup_egl_image(gdrm
->lookup_egl_image_data
, buffer
);
132 if (resource
== NULL
)
140 bo
= CALLOC_STRUCT(gbm_gallium_drm_bo
);
144 bo
->base
.base
.gbm
= gbm
;
145 bo
->base
.base
.width
= resource
->width0
;
146 bo
->base
.base
.height
= resource
->height0
;
148 switch (resource
->format
) {
149 case PIPE_FORMAT_BGRX8888_UNORM
:
150 bo
->base
.base
.format
= GBM_BO_FORMAT_XRGB8888
;
152 case PIPE_FORMAT_BGRA8888_UNORM
:
153 bo
->base
.base
.format
= GBM_BO_FORMAT_ARGB8888
;
160 pipe_resource_reference(&bo
->resource
, resource
);
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
);
166 bo
->base
.base
.handle
.u32
= whandle
.handle
;
167 bo
->base
.base
.stride
= whandle
.stride
;
169 return &bo
->base
.base
;
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
)
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
;
183 bo
= CALLOC_STRUCT(gbm_gallium_drm_bo
);
187 bo
->base
.base
.gbm
= gbm
;
188 bo
->base
.base
.width
= width
;
189 bo
->base
.base
.height
= height
;
190 bo
->base
.base
.format
= format
;
192 pf
= gbm_format_to_gallium(format
);
193 if (pf
== PIPE_FORMAT_NONE
)
196 memset(&templ
, 0, sizeof(templ
));
197 templ
.bind
= gbm_usage_to_gallium(usage
);
199 templ
.target
= PIPE_TEXTURE_2D
;
200 templ
.last_level
= 0;
201 templ
.width0
= width
;
202 templ
.height0
= height
;
204 templ
.array_size
= 1;
206 bo
->resource
= gdrm
->screen
->resource_create(gdrm
->screen
, &templ
);
207 if (bo
->resource
== NULL
) {
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
);
216 bo
->base
.base
.handle
.u32
= whandle
.handle
;
217 bo
->base
.base
.stride
= whandle
.stride
;
219 return &bo
->base
.base
;
223 gbm_gallium_drm_destroy(struct gbm_device
*gbm
)
225 struct gbm_gallium_drm_device
*gdrm
= gbm_gallium_drm_device(gbm
);
227 free(gdrm
->base
.driver_name
);
228 gdrm
->screen
->destroy(gdrm
->screen
);
229 #if !GALLIUM_STATIC_TARGETS
230 pipe_loader_release(&gdrm
->dev
, 1);
235 #if !GALLIUM_STATIC_TARGETS
236 #ifdef HAVE_PIPE_LOADER_DRM
238 get_library_search_path(void)
240 const char *search_path
= NULL
;
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
;
253 static struct gbm_device
*
254 gbm_gallium_drm_device_create(int fd
)
256 struct gbm_gallium_drm_device
*gdrm
;
258 gdrm
= calloc(1, sizeof *gdrm
);
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
;
269 gdrm
->base
.type
= GBM_DRM_DRIVER_TYPE_GALLIUM
;
270 gdrm
->base
.base
.name
= "drm";
272 #if GALLIUM_STATIC_TARGETS
273 gdrm
->screen
= dd_create_screen(gdrm
->base
.base
.fd
);
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 */
282 if (gdrm
->screen
== NULL
)
285 #if GALLIUM_STATIC_TARGETS
286 gdrm
->base
.driver_name
= strdup(dd_driver_name());
288 #ifdef HAVE_PIPE_LOADER_DRM
289 gdrm
->base
.driver_name
= strdup(gdrm
->dev
->driver_name
);
290 #endif /* HAVE_PIPE_LOADER_DRM */
292 return &gdrm
->base
.base
;
295 debug_printf("failed to load gallium_gbm\n");
296 #if !GALLIUM_STATIC_TARGETS
298 pipe_loader_release(&gdrm
->dev
, 1);
305 GBM_EXPORT
struct gbm_backend gbm_backend
= {
306 .backend_name
= "gallium_drm",
307 .create_device
= gbm_gallium_drm_device_create
,