2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include <sys/types.h>
30 #include "util/u_memory.h"
33 #include "native_drm.h"
35 /* see get_drm_screen_name */
36 #include <radeon_drm.h>
37 #include "radeon/drm/radeon_drm.h"
40 drm_display_is_format_supported(struct native_display
*ndpy
,
41 enum pipe_format fmt
, boolean is_color
)
43 return ndpy
->screen
->is_format_supported(ndpy
->screen
,
44 fmt
, PIPE_TEXTURE_2D
, 0,
45 (is_color
) ? PIPE_BIND_RENDER_TARGET
:
46 PIPE_BIND_DEPTH_STENCIL
, 0);
49 static const struct native_config
**
50 drm_display_get_configs(struct native_display
*ndpy
, int *num_configs
)
52 struct drm_display
*drmdpy
= drm_display(ndpy
);
53 const struct native_config
**configs
;
56 if (!drmdpy
->config
) {
57 struct native_config
*nconf
;
58 enum pipe_format format
;
60 drmdpy
->config
= CALLOC(1, sizeof(*drmdpy
->config
));
64 nconf
= &drmdpy
->config
->base
;
67 (1 << NATIVE_ATTACHMENT_FRONT_LEFT
) |
68 (1 << NATIVE_ATTACHMENT_BACK_LEFT
);
70 format
= PIPE_FORMAT_B8G8R8A8_UNORM
;
71 if (!drm_display_is_format_supported(&drmdpy
->base
, format
, TRUE
)) {
72 format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
73 if (!drm_display_is_format_supported(&drmdpy
->base
, format
, TRUE
))
74 format
= PIPE_FORMAT_NONE
;
76 if (format
== PIPE_FORMAT_NONE
) {
78 drmdpy
->config
= NULL
;
82 nconf
->color_format
= format
;
85 if (drmdpy
->resources
)
86 nconf
->scanout_bit
= TRUE
;
89 configs
= MALLOC(sizeof(*configs
));
91 configs
[0] = &drmdpy
->config
->base
;
100 drm_display_get_param(struct native_display
*ndpy
,
101 enum native_param_type param
)
106 case NATIVE_PARAM_USE_NATIVE_BUFFER
:
107 case NATIVE_PARAM_PRESERVE_BUFFER
:
108 case NATIVE_PARAM_MAX_SWAP_INTERVAL
:
118 drm_display_destroy(struct native_display
*ndpy
)
120 struct drm_display
*drmdpy
= drm_display(ndpy
);
123 FREE(drmdpy
->config
);
125 drm_display_fini_modeset(&drmdpy
->base
);
127 if (drmdpy
->base
.screen
)
128 drmdpy
->base
.screen
->destroy(drmdpy
->base
.screen
);
137 get_drm_screen_name(int fd
, drmVersionPtr version
)
139 const char *name
= version
->name
;
141 if (name
&& !strcmp(name
, "radeon")) {
143 struct drm_radeon_info info
;
145 memset(&info
, 0, sizeof(info
));
146 info
.request
= RADEON_INFO_DEVICE_ID
;
147 info
.value
= pointer_to_intptr(&chip_id
);
148 if (drmCommandWriteRead(fd
, DRM_RADEON_INFO
, &info
, sizeof(info
)) != 0)
151 name
= is_r3xx(chip_id
) ? "r300" : "r600";
158 * Initialize KMS and pipe screen.
161 drm_display_init_screen(struct native_display
*ndpy
)
163 struct drm_display
*drmdpy
= drm_display(ndpy
);
164 drmVersionPtr version
;
167 version
= drmGetVersion(drmdpy
->fd
);
169 _eglLog(_EGL_WARNING
, "invalid fd %d", drmdpy
->fd
);
173 name
= get_drm_screen_name(drmdpy
->fd
, version
);
175 drmdpy
->base
.screen
=
176 drmdpy
->event_handler
->new_drm_screen(&drmdpy
->base
, name
, drmdpy
->fd
);
178 drmFreeVersion(version
);
180 if (!drmdpy
->base
.screen
) {
181 _eglLog(_EGL_WARNING
, "failed to create DRM screen");
188 static struct pipe_resource
*
189 drm_display_import_buffer(struct native_display
*ndpy
,
190 const struct pipe_resource
*templ
,
193 return ndpy
->screen
->resource_from_handle(ndpy
->screen
,
194 templ
, (struct winsys_handle
*) buf
);
198 drm_display_export_buffer(struct native_display
*ndpy
,
199 struct pipe_resource
*res
,
202 return ndpy
->screen
->resource_get_handle(ndpy
->screen
,
203 res
, (struct winsys_handle
*) buf
);
206 static struct native_display_buffer drm_display_buffer
= {
207 drm_display_import_buffer
,
208 drm_display_export_buffer
211 static struct native_display
*
212 drm_create_display(int fd
, struct native_event_handler
*event_handler
,
215 struct drm_display
*drmdpy
;
217 drmdpy
= CALLOC_STRUCT(drm_display
);
222 drmdpy
->event_handler
= event_handler
;
223 drmdpy
->base
.user_data
= user_data
;
225 if (!drm_display_init_screen(&drmdpy
->base
)) {
226 drm_display_destroy(&drmdpy
->base
);
230 drmdpy
->base
.destroy
= drm_display_destroy
;
231 drmdpy
->base
.get_param
= drm_display_get_param
;
232 drmdpy
->base
.get_configs
= drm_display_get_configs
;
234 drmdpy
->base
.buffer
= &drm_display_buffer
;
235 drm_display_init_modeset(&drmdpy
->base
);
237 return &drmdpy
->base
;
240 static struct native_display
*
241 native_create_display(void *dpy
, struct native_event_handler
*event_handler
,
247 fd
= dup((int) pointer_to_intptr(dpy
));
250 fd
= open("/dev/dri/card0", O_RDWR
);
255 return drm_create_display(fd
, event_handler
, user_data
);
258 static const struct native_platform drm_platform
= {
260 native_create_display
263 const struct native_platform
*
264 native_get_drm_platform(void)
266 return &drm_platform
;