blob: 19978da110ee256c64bc31cc56858dda77ead639 [file] [log] [blame]
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06001/*
2 * XGL 3-D graphics library
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
Chia-I Wua6e33492014-08-05 13:35:08 +080032#include <stdio.h>
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060033#include <sys/types.h>
34#include <sys/stat.h>
35#include <assert.h>
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060036#include <fcntl.h>
Chia-I Wua6e33492014-08-05 13:35:08 +080037#include <unistd.h>
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060038#include <fnmatch.h>
39
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060040#include <libudev.h>
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060041
Chia-I Wua6e33492014-08-05 13:35:08 +080042#include "gpu.h"
43#include "intel.h"
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060044
Chia-I Wu73019ad2014-08-29 12:01:13 +080045static int intel_devid_override;
Chia-I Wu1c527012014-08-23 14:57:35 +080046int intel_debug = -1;
47
48static void intel_debug_init(void)
49{
50 const char *env;
51
52 if (intel_debug >= 0)
53 return;
54
55 intel_debug = 0;
56
57 /* parse comma-separated debug options */
58 env = getenv("INTEL_DEBUG");
59 while (env) {
60 const char *p = strchr(env, ',');
61 size_t len;
62
63 if (p)
64 len = p - env;
65 else
66 len = strlen(env);
67
Chia-I Wu73019ad2014-08-29 12:01:13 +080068 if (strncmp(env, "batch", len) == 0) {
Chia-I Wu1c527012014-08-23 14:57:35 +080069 intel_debug |= INTEL_DEBUG_BATCH;
Chia-I Wu73019ad2014-08-29 12:01:13 +080070 } else if (strncmp(env, "nohw", len) == 0) {
Chia-I Wu93ada312014-08-23 15:02:25 +080071 intel_debug |= INTEL_DEBUG_NOHW;
Chia-I Wu73019ad2014-08-29 12:01:13 +080072 } else if (strncmp(env, "0x", 2) == 0) {
73 intel_debug |= INTEL_DEBUG_NOHW;
74 intel_devid_override = strtol(env, NULL, 16);
75 }
Chia-I Wu1c527012014-08-23 14:57:35 +080076
77 if (!p)
78 break;
79
80 env = p + 1;
81 }
82}
83
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060084static int is_render_node(int fd, struct stat *st)
85{
86 if (fstat(fd, st))
87 return 0;
88
89 if (!S_ISCHR(st->st_mode))
90 return 0;
91
92 return st->st_rdev & 0x80;
93}
94
Chia-I Wu468e3c32014-08-04 08:03:57 +080095ICD_EXPORT XGL_RESULT XGLAPI xglInitAndEnumerateGpus(const XGL_APPLICATION_INFO *
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060096 pAppInfo,
97 const XGL_ALLOC_CALLBACKS *
98 pAllocCb, XGL_UINT maxGpus,
99 XGL_UINT * pGpuCount,
100 XGL_PHYSICAL_GPU * pGpus)
101{
102 struct udev *udev;
103 struct udev_enumerate *e;
104 struct udev_device *device, *parent;
105 struct udev_list_entry *entry;
106 const char *pci_id, *path;
107 const char *usub, *dnode;
108 int fd;
109 struct stat st;
110 char *pci_glob = "*:*";
Chia-I Wu3065c9c2014-08-04 06:28:31 +0800111 XGL_RESULT ret;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600112 XGL_UINT count = 0;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600113
Chia-I Wu1c527012014-08-23 14:57:35 +0800114 intel_debug_init();
115
Chia-I Wuc217f802014-08-05 10:17:50 +0800116 ret = icd_set_allocator(pAllocCb);
Chia-I Wu3065c9c2014-08-04 06:28:31 +0800117 if (ret != XGL_SUCCESS)
118 return ret;
119
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600120 /*
121 * xglInitAndEnumerateGpus() can be called multiple times. Calling it more than once
122 * forces driver reinitialization.
123 */
Chia-I Wua6e33492014-08-05 13:35:08 +0800124 intel_gpu_remove_all();
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600125
Chia-I Wuc7bff532014-08-06 12:14:54 +0800126 if (!maxGpus) {
127 *pGpuCount = 0;
Chia-I Wua6e33492014-08-05 13:35:08 +0800128 return XGL_SUCCESS;
Chia-I Wuc7bff532014-08-06 12:14:54 +0800129 }
Chia-I Wua6e33492014-08-05 13:35:08 +0800130
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600131 // TODO: Do we need any other validation for incoming pointers?
132
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600133 udev = udev_new();
134 if (udev == NULL) {
Chia-I Wua6e33492014-08-05 13:35:08 +0800135 icd_log(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0,
136 XGL_NULL_HANDLE, 0, 0, "failed to initialize udev context");
137 return XGL_ERROR_OUT_OF_MEMORY;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600138 }
139
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600140 fd = -1;
141 e = udev_enumerate_new(udev);
142 udev_enumerate_add_match_subsystem(e, "drm");
143 udev_enumerate_scan_devices(e);
144 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
Chia-I Wua6e33492014-08-05 13:35:08 +0800145 unsigned int ven_id, dev_id;
146 struct intel_gpu *gpu;
147
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600148 path = udev_list_entry_get_name(entry);
149 device = udev_device_new_from_syspath(udev, path);
150 parent = udev_device_get_parent(device);
151 usub = udev_device_get_subsystem(parent);
152 /* Filter out KMS output devices. */
Chia-I Wu78462db2014-08-06 12:23:55 +0800153 if (!usub || (strcmp(usub, "pci") != 0)) {
154 udev_device_unref(device);
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600155 continue;
Chia-I Wu78462db2014-08-06 12:23:55 +0800156 }
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600157 pci_id = udev_device_get_property_value(parent, "PCI_ID");
Chia-I Wu78462db2014-08-06 12:23:55 +0800158 if (fnmatch(pci_glob, pci_id, 0) != 0) {
159 udev_device_unref(device);
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600160 continue;
Chia-I Wu78462db2014-08-06 12:23:55 +0800161 }
Chia-I Wua6e33492014-08-05 13:35:08 +0800162 sscanf(pci_id, "%x:%x", &ven_id, &dev_id);
Chia-I Wu78462db2014-08-06 12:23:55 +0800163 if (ven_id != 0x8086) {
164 udev_device_unref(device);
Chia-I Wua6e33492014-08-05 13:35:08 +0800165 continue;
Chia-I Wu78462db2014-08-06 12:23:55 +0800166 }
Chia-I Wua6e33492014-08-05 13:35:08 +0800167
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600168 dnode = udev_device_get_devnode(device);
Chia-I Wua6e33492014-08-05 13:35:08 +0800169 /* TODO do not open the device at this point */
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600170 fd = open(dnode, O_RDWR);
Chia-I Wu78462db2014-08-06 12:23:55 +0800171 if (fd < 0) {
172 udev_device_unref(device);
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600173 continue;
Chia-I Wu78462db2014-08-06 12:23:55 +0800174 }
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600175 if (!is_render_node(fd, &st)) {
176 close(fd);
177 fd = -1;
Chia-I Wu78462db2014-08-06 12:23:55 +0800178 udev_device_unref(device);
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600179 continue;
180 }
Chia-I Wua6e33492014-08-05 13:35:08 +0800181 close(fd);
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600182
Chia-I Wu73019ad2014-08-29 12:01:13 +0800183 if (intel_devid_override)
184 dev_id = intel_devid_override;
Chia-I Wua6e33492014-08-05 13:35:08 +0800185 ret = intel_gpu_add(dev_id, dnode, &gpu);
Chia-I Wu78462db2014-08-06 12:23:55 +0800186
187 udev_device_unref(device);
188
Chia-I Wua6e33492014-08-05 13:35:08 +0800189 if (ret == XGL_SUCCESS) {
190 pGpus[count++] = (XGL_PHYSICAL_GPU) gpu;
191 if (count >= maxGpus)
192 break;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600193 }
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600194 }
Chia-I Wua6e33492014-08-05 13:35:08 +0800195
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600196 udev_enumerate_unref(e);
197 udev_unref(udev);
198
Chia-I Wua6e33492014-08-05 13:35:08 +0800199 *pGpuCount = count;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600200
Chia-I Wua6e33492014-08-05 13:35:08 +0800201 return (count > 0) ? XGL_SUCCESS : XGL_ERROR_UNAVAILABLE;
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -0600202}