2 * Mesa 3-D graphics library
5 * Copyright (C) 2010-2011 LunarG Inc.
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 * Chia-I Wu <olv@lunarg.com>
29 #include "common/egl_g3d_loader.h"
30 #include "egldriver.h"
34 #include <stdio.h> /* for sscanf */
38 #define DRIVER_MAP_GALLIUM_ONLY
39 #include "pci_ids/pci_id_driver_map.h"
44 static struct egl_g3d_loader egl_g3d_loader
;
46 static struct st_module
{
49 } st_modules
[ST_API_COUNT
];
51 static struct st_api
*
52 get_st_api(enum st_api_type api
)
54 struct st_module
*stmod
= &st_modules
[api
];
56 if (!stmod
->initialized
) {
57 stmod
->stapi
= egl_st_create_api(api
);
58 stmod
->initialized
= TRUE
;
67 drm_fd_get_pci_id(int fd
, int *vendor_id
, int *chip_id
)
69 struct udev
*udev
= NULL
;
70 struct udev_device
*device
= NULL
, *parent
;
77 if (fstat(fd
, &buf
) < 0) {
78 _eglLog(_EGL_WARNING
, "failed to stat fd %d", fd
);
82 device
= udev_device_new_from_devnum(udev
, 'c', buf
.st_rdev
);
85 "could not create udev device for fd %d", fd
);
89 parent
= udev_device_get_parent(device
);
91 _eglLog(_EGL_WARNING
, "could not get parent device");
95 pci_id
= udev_device_get_property_value(parent
, "PCI_ID");
97 sscanf(pci_id
, "%x:%x", vendor_id
, chip_id
) != 2) {
98 _eglLog(_EGL_WARNING
, "malformed or no PCI ID");
105 udev_device_unref(device
);
109 return (*chip_id
>= 0);
112 #elif defined(PIPE_OS_ANDROID) && !defined(_EGL_NO_DRM)
116 #include <i915_drm.h>
118 #include <radeon_drm.h>
119 /* for util_strcmp */
120 #include "util/u_string.h"
123 drm_fd_get_pci_id(int fd
, int *vendor_id
, int *chip_id
)
125 drmVersionPtr version
;
129 version
= drmGetVersion(fd
);
131 _eglLog(_EGL_WARNING
, "invalid drm fd");
134 if (!version
->name
) {
135 _eglLog(_EGL_WARNING
, "unable to determine the driver name");
136 drmFreeVersion(version
);
140 if (util_strcmp(version
->name
, "i915") == 0) {
141 struct drm_i915_getparam gp
;
146 memset(&gp
, 0, sizeof(gp
));
147 gp
.param
= I915_PARAM_CHIPSET_ID
;
149 ret
= drmCommandWriteRead(fd
, DRM_I915_GETPARAM
, &gp
, sizeof(gp
));
151 _eglLog(_EGL_WARNING
, "failed to get param for i915");
155 else if (util_strcmp(version
->name
, "radeon") == 0) {
156 struct drm_radeon_info info
;
161 memset(&info
, 0, sizeof(info
));
162 info
.request
= RADEON_INFO_DEVICE_ID
;
163 info
.value
= (unsigned long) chip_id
;
164 ret
= drmCommandWriteRead(fd
, DRM_RADEON_INFO
, &info
, sizeof(info
));
166 _eglLog(_EGL_WARNING
, "failed to get info for radeon");
170 else if (util_strcmp(version
->name
, "nouveau") == 0) {
175 else if (util_strcmp(version
->name
, "vmwgfx") == 0) {
181 drmFreeVersion(version
);
183 return (*chip_id
>= 0);
189 drm_fd_get_pci_id(int fd
, int *vendor_id
, int *chip_id
)
194 #endif /* HAVE_LIBUDEV */
197 drm_fd_get_screen_name(int fd
)
199 int vendor_id
, chip_id
;
202 if (!drm_fd_get_pci_id(fd
, &vendor_id
, &chip_id
)) {
203 _eglLog(_EGL_WARNING
, "failed to get driver name for fd %d", fd
);
207 for (idx
= 0; driver_map
[idx
].driver
; idx
++) {
208 if (vendor_id
!= driver_map
[idx
].vendor_id
)
211 /* done if no chip id */
212 if (driver_map
[idx
].num_chips_ids
== -1)
215 for (i
= 0; i
< driver_map
[idx
].num_chips_ids
; i
++) {
216 if (driver_map
[idx
].chip_ids
[i
] == chip_id
)
220 if (i
< driver_map
[idx
].num_chips_ids
)
224 _eglLog((driver_map
[idx
].driver
) ? _EGL_INFO
: _EGL_WARNING
,
225 "pci id for fd %d: %04x:%04x, driver %s",
226 fd
, vendor_id
, chip_id
, driver_map
[idx
].driver
);
228 return driver_map
[idx
].driver
;
231 static struct pipe_screen
*
232 create_drm_screen(const char *name
, int fd
)
234 struct pipe_screen
*screen
;
237 name
= drm_fd_get_screen_name(fd
);
242 screen
= egl_pipe_create_drm_screen(name
, fd
);
244 _eglLog(_EGL_INFO
, "created a pipe screen for %s", name
);
246 _eglLog(_EGL_WARNING
, "failed to create a pipe screen for %s", name
);
251 static struct pipe_screen
*
252 create_sw_screen(struct sw_winsys
*ws
)
254 return egl_pipe_create_swrast_screen(ws
);
257 static const struct egl_g3d_loader
*
262 for (i
= 0; i
< ST_API_COUNT
; i
++)
263 egl_g3d_loader
.profile_masks
[i
] = egl_st_get_profile_mask(i
);
265 egl_g3d_loader
.get_st_api
= get_st_api
;
266 egl_g3d_loader
.create_drm_screen
= create_drm_screen
;
267 egl_g3d_loader
.create_sw_screen
= create_sw_screen
;
269 return &egl_g3d_loader
;
277 for (i
= 0; i
< ST_API_COUNT
; i
++) {
278 struct st_module
*stmod
= &st_modules
[i
];
281 egl_st_destroy_api(stmod
->stapi
);
284 stmod
->initialized
= FALSE
;
289 egl_g3d_unload(_EGLDriver
*drv
)
291 egl_g3d_destroy_driver(drv
);
296 _EGL_MAIN(const char *args
)
298 const struct egl_g3d_loader
*loader
;
301 loader
= loader_init();
302 drv
= egl_g3d_create_driver(loader
);
308 drv
->Name
= "Gallium";
309 drv
->Unload
= egl_g3d_unload
;