18977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu/*
28977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * Mesa 3-D graphics library
349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu * Version:  7.10
48977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *
549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu * Copyright (C) 2010-2011 LunarG Inc.
68977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *
78977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
88977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * copy of this software and associated documentation files (the "Software"),
98977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * to deal in the Software without restriction, including without limitation
108977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the
128977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * Software is furnished to do so, subject to the following conditions:
138977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *
148977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * The above copyright notice and this permission notice shall be included
158977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * in all copies or substantial portions of the Software.
168977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *
178977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
188977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
218977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
228977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
238977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * DEALINGS IN THE SOFTWARE.
248977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *
258977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu * Authors:
268977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu *    Chia-I Wu <olv@lunarg.com>
278977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu */
288977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
298977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu#include "common/egl_g3d_loader.h"
308977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu#include "egldriver.h"
31a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#include "egllog.h"
32a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
33a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#ifdef HAVE_LIBUDEV
34450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu#include <stdio.h> /* for sscanf */
35a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#include <libudev.h>
36a1cadf2b5c3b8f2e33207e81ee4d1476b5f87805Chia-I Wu#endif
37a1cadf2b5c3b8f2e33207e81ee4d1476b5f87805Chia-I Wu
38a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#define DRIVER_MAP_GALLIUM_ONLY
39a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#include "pci_ids/pci_id_driver_map.h"
408977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
4149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#include "egl_pipe.h"
4249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#include "egl_st.h"
4349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
4449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic struct egl_g3d_loader egl_g3d_loader;
4549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
4649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic struct st_module {
4749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   boolean initialized;
4849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   struct st_api *stapi;
4949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu} st_modules[ST_API_COUNT];
505004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu
518977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wustatic struct st_api *
528977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wuget_st_api(enum st_api_type api)
538977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
5449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   struct st_module *stmod = &st_modules[api];
555004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu
5649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   if (!stmod->initialized) {
5749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      stmod->stapi = egl_st_create_api(api);
5849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      stmod->initialized = TRUE;
598977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu   }
608977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
6149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   return stmod->stapi;
628977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
638977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
64a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu#ifdef HAVE_LIBUDEV
65450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
66450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wustatic boolean
67450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wudrm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
68450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu{
69450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   struct udev *udev = NULL;
70450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   struct udev_device *device = NULL, *parent;
71a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   struct stat buf;
72a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   const char *pci_id;
73450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
74450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   *chip_id = -1;
75a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
76a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   udev = udev_new();
77a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   if (fstat(fd, &buf) < 0) {
78a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      _eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
79450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      goto out;
80a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
81a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
82a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
83a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   if (device == NULL) {
84a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      _eglLog(_EGL_WARNING,
85a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu              "could not create udev device for fd %d", fd);
86450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      goto out;
87a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
88a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
89a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   parent = udev_device_get_parent(device);
90a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   if (parent == NULL) {
91a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      _eglLog(_EGL_WARNING, "could not get parent device");
92a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      goto out;
93a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
94a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
95a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   pci_id = udev_device_get_property_value(parent, "PCI_ID");
96a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   if (pci_id == NULL ||
97450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu       sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) {
98a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      _eglLog(_EGL_WARNING, "malformed or no PCI ID");
99450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      *chip_id = -1;
100a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      goto out;
101a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
102a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
103450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wuout:
104450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   if (device)
105450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      udev_device_unref(device);
106450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   if (udev)
107450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      udev_unref(udev);
108450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
109450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   return (*chip_id >= 0);
110450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu}
111450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
11209b5f1fd61bfbb5afdaee81687a9c74c70a62b8aChia-I Wu#elif defined(PIPE_OS_ANDROID) && !defined(_EGL_NO_DRM)
1134b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1144b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu#include <xf86drm.h>
1154b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu/* for i915 */
1164b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu#include <i915_drm.h>
1174b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu/* for radeon */
1184b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu#include <radeon_drm.h>
1194b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu/* for util_strcmp */
1204b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu#include "util/u_string.h"
1214b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1224b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wustatic boolean
1234b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wudrm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
1244b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu{
1254b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   drmVersionPtr version;
1264b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1274b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   *chip_id = -1;
1284b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1294b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   version = drmGetVersion(fd);
1304b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   if (!version) {
1314b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      _eglLog(_EGL_WARNING, "invalid drm fd");
1324b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      return FALSE;
1334b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   }
1344b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   if (!version->name) {
1354b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      _eglLog(_EGL_WARNING, "unable to determine the driver name");
1364b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      drmFreeVersion(version);
1374b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      return FALSE;
1384b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   }
1394b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1404b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   if (util_strcmp(version->name, "i915") == 0) {
1414b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      struct drm_i915_getparam gp;
1424b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      int ret;
1434b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1444b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      *vendor_id = 0x8086;
1454b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1464b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      memset(&gp, 0, sizeof(gp));
1474b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      gp.param = I915_PARAM_CHIPSET_ID;
1484b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      gp.value = chip_id;
1494b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
1504b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      if (ret) {
1514b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu         _eglLog(_EGL_WARNING, "failed to get param for i915");
1524b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu	 *chip_id = -1;
1534b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      }
1544b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   }
1554b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   else if (util_strcmp(version->name, "radeon") == 0) {
1564b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      struct drm_radeon_info info;
1574b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      int ret;
1584b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1594b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      *vendor_id = 0x1002;
1604b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1614b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      memset(&info, 0, sizeof(info));
1624b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      info.request = RADEON_INFO_DEVICE_ID;
1634b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      info.value = (unsigned long) chip_id;
1644b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
1654b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      if (ret) {
1664b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu         _eglLog(_EGL_WARNING, "failed to get info for radeon");
1674b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu	 *chip_id = -1;
1684b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu      }
1694b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   }
170822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu   else if (util_strcmp(version->name, "nouveau") == 0) {
171822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      *vendor_id = 0x10de;
172822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      /* not used */
173822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      *chip_id = 0;
174822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu   }
175822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu   else if (util_strcmp(version->name, "vmwgfx") == 0) {
176822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      *vendor_id = 0x15ad;
177822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      /* assume SVGA II */
178822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu      *chip_id = 0x0405;
179822fad64f8131bacc4ea0b79583d49094543bddcChia-I Wu   }
1804b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1814b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   drmFreeVersion(version);
1824b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
1834b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu   return (*chip_id >= 0);
1844b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu}
1854b2b0b9fb8d41e7a8df4cdc49d498fcfb99139dfChia-I Wu
186450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu#else
187450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
188450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wustatic boolean
189450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wudrm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
190450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu{
191450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   return FALSE;
192450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu}
193450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
194450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu#endif /* HAVE_LIBUDEV */
195450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
196450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wustatic const char *
197450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wudrm_fd_get_screen_name(int fd)
198450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu{
199450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   int vendor_id, chip_id;
200450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   int idx, i;
201450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
202450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   if (!drm_fd_get_pci_id(fd, &vendor_id, &chip_id)) {
203450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd);
204450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      return NULL;
205450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   }
206450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu
207a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   for (idx = 0; driver_map[idx].driver; idx++) {
208a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      if (vendor_id != driver_map[idx].vendor_id)
209a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu         continue;
210a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
211450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      /* done if no chip id */
212a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      if (driver_map[idx].num_chips_ids == -1)
213450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu         break;
214a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
215a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
216a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu         if (driver_map[idx].chip_ids[i] == chip_id)
217450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu            break;
218a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      }
219450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      /* matched! */
220450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu      if (i < driver_map[idx].num_chips_ids)
221450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu         break;
222a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
223a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
224450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING,
225450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu         "pci id for fd %d: %04x:%04x, driver %s",
226450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu         fd, vendor_id, chip_id, driver_map[idx].driver);
227a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
228450f48627684c6ea1472b4fdd51c6fc121f2bc9cChia-I Wu   return driver_map[idx].driver;
229a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu}
230a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
2318977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wustatic struct pipe_screen *
2328977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wucreate_drm_screen(const char *name, int fd)
2338977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
234b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu   struct pipe_screen *screen;
235b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu
236a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   if (!name) {
237a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      name = drm_fd_get_screen_name(fd);
238a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu      if (!name)
239a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu         return NULL;
240a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu   }
241a000745f80f695cfa0cd1dc206869eeb5f87f36fChia-I Wu
242b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu   screen = egl_pipe_create_drm_screen(name, fd);
243b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu   if (screen)
244b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu      _eglLog(_EGL_INFO, "created a pipe screen for %s", name);
245b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu   else
246b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu      _eglLog(_EGL_WARNING, "failed to create a pipe screen for %s", name);
247b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu
248b71a7a2f37ec3693b8f3a7f1acb0c59ed076f104Chia-I Wu   return screen;
2498977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
2508977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
2518977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wustatic struct pipe_screen *
2528977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wucreate_sw_screen(struct sw_winsys *ws)
2538977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
25449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   return egl_pipe_create_swrast_screen(ws);
2558977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
2568977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
25749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic const struct egl_g3d_loader *
25849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wuloader_init(void)
2598977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
26049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   int i;
26149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
26249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   for (i = 0; i < ST_API_COUNT; i++)
26349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      egl_g3d_loader.profile_masks[i] = egl_st_get_profile_mask(i);
26449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
26549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   egl_g3d_loader.get_st_api = get_st_api;
26649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   egl_g3d_loader.create_drm_screen = create_drm_screen;
26749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   egl_g3d_loader.create_sw_screen = create_sw_screen;
26849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
26949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   return &egl_g3d_loader;
2708977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
2718977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
2728977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wustatic void
27349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wuloader_fini(void)
2748977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
2755004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu   int i;
2765004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu
2775004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu   for (i = 0; i < ST_API_COUNT; i++) {
27849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      struct st_module *stmod = &st_modules[i];
27949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
28049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      if (stmod->stapi) {
2817451bffad41a8ab7c61c9799b351c031852eb780Chia-I Wu         egl_st_destroy_api(stmod->stapi);
28249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu         stmod->stapi = NULL;
2835004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu      }
28449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      stmod->initialized = FALSE;
2855004f823ad3c82ec0b50822a4889798c81ce1cfcChia-I Wu   }
2868977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
2878977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
28849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic void
28949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wuegl_g3d_unload(_EGLDriver *drv)
29049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu{
29149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   egl_g3d_destroy_driver(drv);
29249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   loader_fini();
29349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu}
2948977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
2958977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu_EGLDriver *
29649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu_EGL_MAIN(const char *args)
2978977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu{
29849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   const struct egl_g3d_loader *loader;
2998977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu   _EGLDriver *drv;
3008977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
30149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   loader = loader_init();
30249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   drv = egl_g3d_create_driver(loader);
30349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   if (!drv) {
30449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      loader_fini();
30549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu      return NULL;
3068977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu   }
3078977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu
30849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   drv->Name = "Gallium";
30949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu   drv->Unload = egl_g3d_unload;
31049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu
3118977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu   return drv;
3128977879ec91b21572abd9bb95dcd0e72ba49f753Chia-I Wu}
313