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>
36 #include <sys/types.h>
41 #include <GL/gl.h> /* dri_interface needs GL types */
42 #include <GL/internal/dri_interface.h>
44 #include "gbm_driint.h"
49 /* For importing wl_buffer */
50 #if HAVE_WAYLAND_PLATFORM
51 #include "../../../egl/wayland/wayland-drm/wayland-drm.h"
55 dri_lookup_egl_image(__DRIscreen
*screen
, void *image
, void *data
)
57 struct gbm_dri_device
*dri
= data
;
59 if (dri
->lookup_image
== NULL
)
62 return dri
->lookup_image(screen
, image
, dri
->lookup_user_data
);
66 dri_get_buffers(__DRIdrawable
* driDrawable
,
67 int *width
, int *height
,
68 unsigned int *attachments
, int count
,
69 int *out_count
, void *data
)
71 struct gbm_dri_surface
*surf
= data
;
72 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
74 if (dri
->get_buffers
== NULL
)
77 return dri
->get_buffers(driDrawable
, width
, height
, attachments
,
78 count
, out_count
, surf
->dri_private
);
82 dri_flush_front_buffer(__DRIdrawable
* driDrawable
, void *data
)
84 struct gbm_dri_surface
*surf
= data
;
85 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
87 if (dri
->flush_front_buffer
!= NULL
)
88 dri
->flush_front_buffer(driDrawable
, surf
->dri_private
);
92 dri_get_buffers_with_format(__DRIdrawable
* driDrawable
,
93 int *width
, int *height
,
94 unsigned int *attachments
, int count
,
95 int *out_count
, void *data
)
97 struct gbm_dri_surface
*surf
= data
;
98 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
100 if (dri
->get_buffers_with_format
== NULL
)
104 dri
->get_buffers_with_format(driDrawable
, width
, height
, attachments
,
105 count
, out_count
, surf
->dri_private
);
109 image_get_buffers(__DRIdrawable
*driDrawable
,
113 uint32_t buffer_mask
,
114 struct __DRIimageList
*buffers
)
116 struct gbm_dri_surface
*surf
= loaderPrivate
;
117 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
119 if (dri
->image_get_buffers
== NULL
)
122 return dri
->image_get_buffers(driDrawable
, format
, stamp
,
123 surf
->dri_private
, buffer_mask
, buffers
);
127 swrast_get_drawable_info(__DRIdrawable
*driDrawable
,
134 struct gbm_dri_surface
*surf
= loaderPrivate
;
138 *width
= surf
->base
.width
;
139 *height
= surf
->base
.height
;
143 swrast_put_image2(__DRIdrawable
*driDrawable
,
153 struct gbm_dri_surface
*surf
= loaderPrivate
;
154 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
156 dri
->swrast_put_image2(driDrawable
,
158 width
, height
, stride
,
159 data
, surf
->dri_private
);
163 swrast_put_image(__DRIdrawable
*driDrawable
,
172 return swrast_put_image2(driDrawable
, op
, x
, y
, width
, height
,
173 width
* 4, data
, loaderPrivate
);
177 swrast_get_image(__DRIdrawable
*driDrawable
,
185 struct gbm_dri_surface
*surf
= loaderPrivate
;
186 struct gbm_dri_device
*dri
= gbm_dri_device(surf
->base
.gbm
);
188 dri
->swrast_get_image(driDrawable
,
191 data
, surf
->dri_private
);
194 static const __DRIuseInvalidateExtension use_invalidate
= {
195 .base
= { __DRI_USE_INVALIDATE
, 1 }
198 static const __DRIimageLookupExtension image_lookup_extension
= {
199 .base
= { __DRI_IMAGE_LOOKUP
, 1 },
201 .lookupEGLImage
= dri_lookup_egl_image
204 static const __DRIdri2LoaderExtension dri2_loader_extension
= {
205 .base
= { __DRI_DRI2_LOADER
, 3 },
207 .getBuffers
= dri_get_buffers
,
208 .flushFrontBuffer
= dri_flush_front_buffer
,
209 .getBuffersWithFormat
= dri_get_buffers_with_format
,
212 static const __DRIimageLoaderExtension image_loader_extension
= {
213 .base
= { __DRI_IMAGE_LOADER
, 1 },
215 .getBuffers
= image_get_buffers
,
216 .flushFrontBuffer
= dri_flush_front_buffer
,
219 static const __DRIswrastLoaderExtension swrast_loader_extension
= {
220 .base
= { __DRI_SWRAST_LOADER
, 2 },
222 .getDrawableInfo
= swrast_get_drawable_info
,
223 .putImage
= swrast_put_image
,
224 .getImage
= swrast_get_image
,
225 .putImage2
= swrast_put_image2
228 static const __DRIextension
*gbm_dri_screen_extensions
[] = {
229 &image_lookup_extension
.base
,
230 &use_invalidate
.base
,
231 &dri2_loader_extension
.base
,
232 &image_loader_extension
.base
,
233 &swrast_loader_extension
.base
,
237 struct dri_extension_match
{
243 static struct dri_extension_match dri_core_extensions
[] = {
244 { __DRI2_FLUSH
, 1, offsetof(struct gbm_dri_device
, flush
) },
245 { __DRI_IMAGE
, 1, offsetof(struct gbm_dri_device
, image
) },
249 static struct dri_extension_match gbm_dri_device_extensions
[] = {
250 { __DRI_CORE
, 1, offsetof(struct gbm_dri_device
, core
) },
251 { __DRI_DRI2
, 1, offsetof(struct gbm_dri_device
, dri2
) },
255 static struct dri_extension_match gbm_swrast_device_extensions
[] = {
256 { __DRI_CORE
, 1, offsetof(struct gbm_dri_device
, core
), },
257 { __DRI_SWRAST
, 1, offsetof(struct gbm_dri_device
, swrast
) },
262 dri_bind_extensions(struct gbm_dri_device
*dri
,
263 struct dri_extension_match
*matches
,
264 const __DRIextension
**extensions
)
269 for (i
= 0; extensions
[i
]; i
++) {
270 for (j
= 0; matches
[j
].name
; j
++) {
271 if (strcmp(extensions
[i
]->name
, matches
[j
].name
) == 0 &&
272 extensions
[i
]->version
>= matches
[j
].version
) {
273 field
= ((char *) dri
+ matches
[j
].offset
);
274 *(const __DRIextension
**) field
= extensions
[i
];
279 for (j
= 0; matches
[j
].name
; j
++) {
280 field
= ((char *) dri
+ matches
[j
].offset
);
281 if (*(const __DRIextension
**) field
== NULL
) {
289 static const __DRIextension
**
290 dri_open_driver(struct gbm_dri_device
*dri
)
292 const __DRIextension
**extensions
= NULL
;
293 char path
[PATH_MAX
], *search_paths
, *p
, *next
, *end
;
294 char *get_extensions_name
;
297 /* don't allow setuid apps to use LIBGL_DRIVERS_PATH or GBM_DRIVERS_PATH */
298 if (geteuid() == getuid()) {
299 /* Read GBM_DRIVERS_PATH first for compatibility, but LIBGL_DRIVERS_PATH
300 * is recommended over GBM_DRIVERS_PATH.
302 search_paths
= getenv("GBM_DRIVERS_PATH");
304 /* Read LIBGL_DRIVERS_PATH if GBM_DRIVERS_PATH was not set.
305 * LIBGL_DRIVERS_PATH is recommended over GBM_DRIVERS_PATH.
307 if (search_paths
== NULL
) {
308 search_paths
= getenv("LIBGL_DRIVERS_PATH");
311 if (search_paths
== NULL
)
312 search_paths
= DEFAULT_DRIVER_DIR
;
314 /* Temporarily work around dri driver libs that need symbols in libglapi
315 * but don't automatically link it in.
317 /* XXX: Library name differs on per platforms basis. Update this as
318 * osx/cygwin/windows/bsd gets support for GBM..
320 dlopen("libglapi.so.0", RTLD_LAZY
| RTLD_GLOBAL
);
323 end
= search_paths
+ strlen(search_paths
);
324 for (p
= search_paths
; p
< end
&& dri
->driver
== NULL
; p
= next
+ 1) {
326 next
= strchr(p
, ':');
332 snprintf(path
, sizeof path
,
333 "%.*s/tls/%s_dri.so", len
, p
, dri
->base
.driver_name
);
334 dri
->driver
= dlopen(path
, RTLD_NOW
| RTLD_GLOBAL
);
336 if (dri
->driver
== NULL
) {
337 snprintf(path
, sizeof path
,
338 "%.*s/%s_dri.so", len
, p
, dri
->base
.driver_name
);
339 dri
->driver
= dlopen(path
, RTLD_NOW
| RTLD_GLOBAL
);
341 /* not need continue to loop all paths once the driver is found */
342 if (dri
->driver
!= NULL
)
346 if (dri
->driver
== NULL
) {
347 fprintf(stderr
, "gbm: failed to open any driver (search paths %s)\n",
349 fprintf(stderr
, "gbm: Last dlopen error: %s\n", dlerror());
353 if (asprintf(&get_extensions_name
, "%s_%s",
354 __DRI_DRIVER_GET_EXTENSIONS
, dri
->base
.driver_name
) != -1) {
355 const __DRIextension
**(*get_extensions
)(void);
357 get_extensions
= dlsym(dri
->driver
, get_extensions_name
);
358 free(get_extensions_name
);
361 extensions
= get_extensions();
365 extensions
= dlsym(dri
->driver
, __DRI_DRIVER_EXTENSIONS
);
366 if (extensions
== NULL
) {
367 fprintf(stderr
, "gbm: driver exports no extensions (%s)", dlerror());
368 dlclose(dri
->driver
);
375 dri_load_driver(struct gbm_dri_device
*dri
)
377 const __DRIextension
**extensions
;
379 extensions
= dri_open_driver(dri
);
383 if (dri_bind_extensions(dri
, gbm_dri_device_extensions
, extensions
) < 0) {
384 dlclose(dri
->driver
);
385 fprintf(stderr
, "failed to bind extensions\n");
389 dri
->driver_extensions
= extensions
;
395 dri_load_driver_swrast(struct gbm_dri_device
*dri
)
397 const __DRIextension
**extensions
;
399 extensions
= dri_open_driver(dri
);
403 if (dri_bind_extensions(dri
, gbm_swrast_device_extensions
, extensions
) < 0) {
404 dlclose(dri
->driver
);
405 fprintf(stderr
, "failed to bind extensions\n");
409 dri
->driver_extensions
= extensions
;
415 dri_screen_create_dri2(struct gbm_dri_device
*dri
, char *driver_name
)
417 const __DRIextension
**extensions
;
420 dri
->base
.driver_name
= driver_name
;
421 if (dri
->base
.driver_name
== NULL
)
424 ret
= dri_load_driver(dri
);
426 fprintf(stderr
, "failed to load driver: %s\n", dri
->base
.driver_name
);
430 dri
->extensions
= gbm_dri_screen_extensions
;
432 if (dri
->dri2
== NULL
)
435 if (dri
->dri2
->base
.version
>= 4) {
436 dri
->screen
= dri
->dri2
->createNewScreen2(0, dri
->base
.base
.fd
,
438 dri
->driver_extensions
,
439 &dri
->driver_configs
, dri
);
441 dri
->screen
= dri
->dri2
->createNewScreen(0, dri
->base
.base
.fd
,
443 &dri
->driver_configs
, dri
);
445 if (dri
->screen
== NULL
)
448 extensions
= dri
->core
->getExtensions(dri
->screen
);
449 if (dri_bind_extensions(dri
, dri_core_extensions
, extensions
) < 0) {
454 dri
->lookup_image
= NULL
;
455 dri
->lookup_user_data
= NULL
;
460 dri
->core
->destroyScreen(dri
->screen
);
466 dri_screen_create_swrast(struct gbm_dri_device
*dri
)
470 dri
->base
.driver_name
= strdup("swrast");
471 if (dri
->base
.driver_name
== NULL
)
474 ret
= dri_load_driver_swrast(dri
);
476 fprintf(stderr
, "failed to load swrast driver\n");
480 dri
->extensions
= gbm_dri_screen_extensions
;
482 if (dri
->swrast
== NULL
)
485 if (dri
->swrast
->base
.version
>= 4) {
486 dri
->screen
= dri
->swrast
->createNewScreen2(0, dri
->extensions
,
487 dri
->driver_extensions
,
488 &dri
->driver_configs
, dri
);
490 dri
->screen
= dri
->swrast
->createNewScreen(0, dri
->extensions
,
491 &dri
->driver_configs
, dri
);
493 if (dri
->screen
== NULL
)
496 dri
->lookup_image
= NULL
;
497 dri
->lookup_user_data
= NULL
;
503 dri_screen_create(struct gbm_dri_device
*dri
)
507 driver_name
= loader_get_driver_for_fd(dri
->base
.base
.fd
, 0);
511 return dri_screen_create_dri2(dri
, driver_name
);
515 dri_screen_create_sw(struct gbm_dri_device
*dri
)
520 driver_name
= strdup("kms_swrast");
524 ret
= dri_screen_create_dri2(dri
, driver_name
);
528 return dri_screen_create_swrast(dri
);
532 gbm_dri_is_format_supported(struct gbm_device
*gbm
,
537 case GBM_BO_FORMAT_XRGB8888
:
538 case GBM_FORMAT_XBGR8888
:
539 case GBM_FORMAT_XRGB8888
:
541 case GBM_BO_FORMAT_ARGB8888
:
542 case GBM_FORMAT_ARGB8888
:
543 if (usage
& GBM_BO_USE_SCANOUT
)
550 if (usage
& GBM_BO_USE_CURSOR
&&
551 usage
& GBM_BO_USE_RENDERING
)
558 gbm_dri_bo_write(struct gbm_bo
*_bo
, const void *buf
, size_t count
)
560 struct gbm_dri_bo
*bo
= gbm_dri_bo(_bo
);
562 if (bo
->image
!= NULL
) {
567 memcpy(bo
->map
, buf
, count
);
573 gbm_dri_bo_get_fd(struct gbm_bo
*_bo
)
575 struct gbm_dri_device
*dri
= gbm_dri_device(_bo
->gbm
);
576 struct gbm_dri_bo
*bo
= gbm_dri_bo(_bo
);
579 if (bo
->image
== NULL
)
582 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_FD
, &fd
);
588 gbm_dri_bo_destroy(struct gbm_bo
*_bo
)
590 struct gbm_dri_device
*dri
= gbm_dri_device(_bo
->gbm
);
591 struct gbm_dri_bo
*bo
= gbm_dri_bo(_bo
);
592 struct drm_mode_destroy_dumb arg
;
594 if (bo
->image
!= NULL
) {
595 dri
->image
->destroyImage(bo
->image
);
597 gbm_dri_bo_unmap(bo
);
598 memset(&arg
, 0, sizeof(arg
));
599 arg
.handle
= bo
->handle
;
600 drmIoctl(dri
->base
.base
.fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &arg
);
607 gbm_dri_to_gbm_format(uint32_t dri_format
)
611 switch (dri_format
) {
612 case __DRI_IMAGE_FORMAT_RGB565
:
613 ret
= GBM_FORMAT_RGB565
;
615 case __DRI_IMAGE_FORMAT_XRGB8888
:
616 ret
= GBM_FORMAT_XRGB8888
;
618 case __DRI_IMAGE_FORMAT_ARGB8888
:
619 ret
= GBM_FORMAT_ARGB8888
;
621 case __DRI_IMAGE_FORMAT_XBGR8888
:
622 ret
= GBM_FORMAT_XBGR8888
;
624 case __DRI_IMAGE_FORMAT_ABGR8888
:
625 ret
= GBM_FORMAT_ABGR8888
;
635 static struct gbm_bo
*
636 gbm_dri_bo_import(struct gbm_device
*gbm
,
637 uint32_t type
, void *buffer
, uint32_t usage
)
639 struct gbm_dri_device
*dri
= gbm_dri_device(gbm
);
640 struct gbm_dri_bo
*bo
;
642 unsigned dri_use
= 0;
645 /* Required for query image WIDTH & HEIGHT */
646 if (dri
->image
== NULL
|| dri
->image
->base
.version
< 4) {
652 #if HAVE_WAYLAND_PLATFORM
653 case GBM_BO_IMPORT_WL_BUFFER
:
655 struct wl_drm_buffer
*wb
;
662 wb
= wayland_drm_buffer_get(dri
->wl_drm
, (struct wl_resource
*) buffer
);
668 image
= dri
->image
->dupImage(wb
->driver_buffer
, NULL
);
670 switch (wb
->format
) {
671 case WL_DRM_FORMAT_XRGB8888
:
672 gbm_format
= GBM_FORMAT_XRGB8888
;
674 case WL_DRM_FORMAT_ARGB8888
:
675 gbm_format
= GBM_FORMAT_ARGB8888
;
677 case WL_DRM_FORMAT_RGB565
:
678 gbm_format
= GBM_FORMAT_RGB565
;
680 case WL_DRM_FORMAT_YUYV
:
681 gbm_format
= GBM_FORMAT_YUYV
;
690 case GBM_BO_IMPORT_EGL_IMAGE
:
693 if (dri
->lookup_image
== NULL
) {
698 image
= dri
->lookup_image(dri
->screen
, buffer
, dri
->lookup_user_data
);
699 image
= dri
->image
->dupImage(image
, NULL
);
700 dri
->image
->queryImage(image
, __DRI_IMAGE_ATTRIB_FORMAT
, &dri_format
);
701 gbm_format
= gbm_dri_to_gbm_format(dri_format
);
702 if (gbm_format
== 0) {
709 case GBM_BO_IMPORT_FD
:
711 struct gbm_import_fd_data
*fd_data
= buffer
;
712 int stride
= fd_data
->stride
, offset
= 0;
715 switch (fd_data
->format
) {
716 case GBM_BO_FORMAT_XRGB8888
:
717 dri_format
= GBM_FORMAT_XRGB8888
;
719 case GBM_BO_FORMAT_ARGB8888
:
720 dri_format
= GBM_FORMAT_ARGB8888
;
723 dri_format
= fd_data
->format
;
726 image
= dri
->image
->createImageFromFds(dri
->screen
,
737 gbm_format
= fd_data
->format
;
747 bo
= calloc(1, sizeof *bo
);
753 if (usage
& GBM_BO_USE_SCANOUT
)
754 dri_use
|= __DRI_IMAGE_USE_SCANOUT
;
755 if (usage
& GBM_BO_USE_CURSOR
)
756 dri_use
|= __DRI_IMAGE_USE_CURSOR
;
757 if (dri
->image
->base
.version
>= 2 &&
758 !dri
->image
->validateUsage(bo
->image
, dri_use
)) {
764 bo
->base
.base
.gbm
= gbm
;
765 bo
->base
.base
.format
= gbm_format
;
767 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_WIDTH
,
768 (int*)&bo
->base
.base
.width
);
769 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_HEIGHT
,
770 (int*)&bo
->base
.base
.height
);
771 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_STRIDE
,
772 (int*)&bo
->base
.base
.stride
);
773 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_HANDLE
,
774 &bo
->base
.base
.handle
.s32
);
776 return &bo
->base
.base
;
779 static struct gbm_bo
*
780 create_dumb(struct gbm_device
*gbm
,
781 uint32_t width
, uint32_t height
,
782 uint32_t format
, uint32_t usage
)
784 struct gbm_dri_device
*dri
= gbm_dri_device(gbm
);
785 struct drm_mode_create_dumb create_arg
;
786 struct gbm_dri_bo
*bo
;
787 struct drm_mode_destroy_dumb destroy_arg
;
789 int is_cursor
, is_scanout
;
791 is_cursor
= (usage
& GBM_BO_USE_CURSOR
) != 0 &&
792 format
== GBM_FORMAT_ARGB8888
;
793 is_scanout
= (usage
& GBM_BO_USE_SCANOUT
) != 0 &&
794 format
== GBM_FORMAT_XRGB8888
;
795 if (!is_cursor
&& !is_scanout
) {
800 bo
= calloc(1, sizeof *bo
);
804 memset(&create_arg
, 0, sizeof(create_arg
));
806 create_arg
.width
= width
;
807 create_arg
.height
= height
;
809 ret
= drmIoctl(dri
->base
.base
.fd
, DRM_IOCTL_MODE_CREATE_DUMB
, &create_arg
);
813 bo
->base
.base
.gbm
= gbm
;
814 bo
->base
.base
.width
= width
;
815 bo
->base
.base
.height
= height
;
816 bo
->base
.base
.stride
= create_arg
.pitch
;
817 bo
->base
.base
.format
= format
;
818 bo
->base
.base
.handle
.u32
= create_arg
.handle
;
819 bo
->handle
= create_arg
.handle
;
820 bo
->size
= create_arg
.size
;
822 if (gbm_dri_bo_map(bo
) == NULL
)
825 return &bo
->base
.base
;
828 memset(&destroy_arg
, 0, sizeof destroy_arg
);
829 destroy_arg
.handle
= create_arg
.handle
;
830 drmIoctl(dri
->base
.base
.fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &destroy_arg
);
837 static struct gbm_bo
*
838 gbm_dri_bo_create(struct gbm_device
*gbm
,
839 uint32_t width
, uint32_t height
,
840 uint32_t format
, uint32_t usage
)
842 struct gbm_dri_device
*dri
= gbm_dri_device(gbm
);
843 struct gbm_dri_bo
*bo
;
845 unsigned dri_use
= 0;
847 if (usage
& GBM_BO_USE_WRITE
|| dri
->image
== NULL
)
848 return create_dumb(gbm
, width
, height
, format
, usage
);
850 bo
= calloc(1, sizeof *bo
);
854 bo
->base
.base
.gbm
= gbm
;
855 bo
->base
.base
.width
= width
;
856 bo
->base
.base
.height
= height
;
857 bo
->base
.base
.format
= format
;
860 case GBM_FORMAT_RGB565
:
861 dri_format
=__DRI_IMAGE_FORMAT_RGB565
;
863 case GBM_FORMAT_XRGB8888
:
864 case GBM_BO_FORMAT_XRGB8888
:
865 dri_format
= __DRI_IMAGE_FORMAT_XRGB8888
;
867 case GBM_FORMAT_ARGB8888
:
868 case GBM_BO_FORMAT_ARGB8888
:
869 dri_format
= __DRI_IMAGE_FORMAT_ARGB8888
;
871 case GBM_FORMAT_ABGR8888
:
872 dri_format
= __DRI_IMAGE_FORMAT_ABGR8888
;
874 case GBM_FORMAT_XBGR8888
:
875 dri_format
= __DRI_IMAGE_FORMAT_XBGR8888
;
877 case GBM_FORMAT_ARGB2101010
:
878 dri_format
= __DRI_IMAGE_FORMAT_ARGB2101010
;
880 case GBM_FORMAT_XRGB2101010
:
881 dri_format
= __DRI_IMAGE_FORMAT_XRGB2101010
;
888 if (usage
& GBM_BO_USE_SCANOUT
)
889 dri_use
|= __DRI_IMAGE_USE_SCANOUT
;
890 if (usage
& GBM_BO_USE_CURSOR
)
891 dri_use
|= __DRI_IMAGE_USE_CURSOR
;
892 if (usage
& GBM_BO_USE_LINEAR
)
893 dri_use
|= __DRI_IMAGE_USE_LINEAR
;
895 /* Gallium drivers requires shared in order to get the handle/stride */
896 dri_use
|= __DRI_IMAGE_USE_SHARE
;
899 dri
->image
->createImage(dri
->screen
,
903 if (bo
->image
== NULL
)
906 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_HANDLE
,
907 &bo
->base
.base
.handle
.s32
);
908 dri
->image
->queryImage(bo
->image
, __DRI_IMAGE_ATTRIB_STRIDE
,
909 (int *) &bo
->base
.base
.stride
);
911 return &bo
->base
.base
;
918 static struct gbm_surface
*
919 gbm_dri_surface_create(struct gbm_device
*gbm
,
920 uint32_t width
, uint32_t height
,
921 uint32_t format
, uint32_t flags
)
923 struct gbm_dri_surface
*surf
;
925 surf
= calloc(1, sizeof *surf
);
929 surf
->base
.gbm
= gbm
;
930 surf
->base
.width
= width
;
931 surf
->base
.height
= height
;
932 surf
->base
.format
= format
;
933 surf
->base
.flags
= flags
;
939 gbm_dri_surface_destroy(struct gbm_surface
*_surf
)
941 struct gbm_dri_surface
*surf
= gbm_dri_surface(_surf
);
947 dri_destroy(struct gbm_device
*gbm
)
949 struct gbm_dri_device
*dri
= gbm_dri_device(gbm
);
952 dri
->core
->destroyScreen(dri
->screen
);
953 for (i
= 0; dri
->driver_configs
[i
]; i
++)
954 free((__DRIconfig
*) dri
->driver_configs
[i
]);
955 free(dri
->driver_configs
);
956 dlclose(dri
->driver
);
957 free(dri
->base
.driver_name
);
962 static struct gbm_device
*
963 dri_device_create(int fd
)
965 struct gbm_dri_device
*dri
;
968 dri
= calloc(1, sizeof *dri
);
972 dri
->base
.base
.fd
= fd
;
973 dri
->base
.base
.bo_create
= gbm_dri_bo_create
;
974 dri
->base
.base
.bo_import
= gbm_dri_bo_import
;
975 dri
->base
.base
.is_format_supported
= gbm_dri_is_format_supported
;
976 dri
->base
.base
.bo_write
= gbm_dri_bo_write
;
977 dri
->base
.base
.bo_get_fd
= gbm_dri_bo_get_fd
;
978 dri
->base
.base
.bo_destroy
= gbm_dri_bo_destroy
;
979 dri
->base
.base
.destroy
= dri_destroy
;
980 dri
->base
.base
.surface_create
= gbm_dri_surface_create
;
981 dri
->base
.base
.surface_destroy
= gbm_dri_surface_destroy
;
983 dri
->base
.type
= GBM_DRM_DRIVER_TYPE_DRI
;
984 dri
->base
.base
.name
= "drm";
986 force_sw
= getenv("GBM_ALWAYS_SOFTWARE") != NULL
;
988 ret
= dri_screen_create(dri
);
990 ret
= dri_screen_create_sw(dri
);
992 ret
= dri_screen_create_sw(dri
);
998 return &dri
->base
.base
;
1006 struct gbm_backend gbm_dri_backend
= {
1007 .backend_name
= "dri",
1008 .create_device
= dri_device_create
,