blob: bff0551465bc1ad71e9e0cb67d26cfa72493dacb [file] [log] [blame]
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06001/*
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06002 * Vulkan 3-D graphics library
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06003 *
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:
Chia-I Wu44e42362014-09-02 08:32:09 +080025 * Courtney Goeltzenleuchter <courtney@lunarg.com>
26 * Chia-I Wu <olv@lunarg.com>
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060027 */
28
Chia-I Wu023ef682014-09-15 11:06:50 +080029#include "icd-enumerate-drm.h"
Chia-I Wua6e33492014-08-05 13:35:08 +080030#include "gpu.h"
Chia-I Wu94ae71a2015-02-20 12:26:08 -070031#include "instance.h"
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060032
Chia-I Wu73019ad2014-08-29 12:01:13 +080033static int intel_devid_override;
Chia-I Wu1c527012014-08-23 14:57:35 +080034int intel_debug = -1;
35
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060036void *intel_alloc(const void *handle,
37 size_t size, size_t alignment,
Chia-I Wu69f40122015-10-26 21:10:41 +080038 VkSystemAllocScope scope)
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060039{
40 assert(intel_handle_validate(handle));
41 return icd_instance_alloc(((const struct intel_handle *) handle)->instance->icd,
Chia-I Wu69f40122015-10-26 21:10:41 +080042 size, alignment, scope);
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060043}
44
45void intel_free(const void *handle, void *ptr)
46{
47 assert(intel_handle_validate(handle));
48 icd_instance_free(((const struct intel_handle *) handle)->instance->icd, ptr);
49}
50
51void intel_logv(const void *handle,
52 VkFlags msg_flags,
Tony Barbourde4124d2015-07-03 10:33:54 -060053 VkDbgObjectType obj_type, uint64_t src_object,
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060054 size_t location, int32_t msg_code,
55 const char *format, va_list ap)
56{
57 char msg[256];
58 int ret;
59
60 ret = vsnprintf(msg, sizeof(msg), format, ap);
61 if (ret >= sizeof(msg) || ret < 0)
62 msg[sizeof(msg) - 1] = '\0';
63
64 assert(intel_handle_validate(handle));
65 icd_instance_log(((const struct intel_handle *) handle)->instance->icd,
66 msg_flags,
67 obj_type, src_object, /* obj_type, object */
68 location, msg_code, /* location, msg_code */
69 msg);
70}
71
Chia-I Wu1c527012014-08-23 14:57:35 +080072static void intel_debug_init(void)
73{
74 const char *env;
75
76 if (intel_debug >= 0)
77 return;
78
79 intel_debug = 0;
80
81 /* parse comma-separated debug options */
Courtney Goeltzenleuchter893f2872015-07-29 09:08:22 -060082 env = getenv("VK_INTEL_DEBUG");
Chia-I Wu1c527012014-08-23 14:57:35 +080083 while (env) {
84 const char *p = strchr(env, ',');
85 size_t len;
86
87 if (p)
88 len = p - env;
89 else
90 len = strlen(env);
91
Courtney Goeltzenleuchterd9fc9842014-10-13 12:58:25 -060092 if (len > 0) {
93 if (strncmp(env, "batch", len) == 0) {
94 intel_debug |= INTEL_DEBUG_BATCH;
95 } else if (strncmp(env, "nohw", len) == 0) {
96 intel_debug |= INTEL_DEBUG_NOHW;
Chia-I Wu3fb47ce2014-10-28 11:19:36 +080097 } else if (strncmp(env, "nocache", len) == 0) {
98 intel_debug |= INTEL_DEBUG_NOCACHE;
Chia-I Wuc45db532015-02-19 11:20:38 -070099 } else if (strncmp(env, "nohiz", len) == 0) {
100 intel_debug |= INTEL_DEBUG_NOHIZ;
Chia-I Wu465fe212015-02-11 11:27:06 -0700101 } else if (strncmp(env, "hang", len) == 0) {
102 intel_debug |= INTEL_DEBUG_HANG;
Courtney Goeltzenleuchterd9fc9842014-10-13 12:58:25 -0600103 } else if (strncmp(env, "0x", 2) == 0) {
104 intel_debug |= INTEL_DEBUG_NOHW;
105 intel_devid_override = strtol(env, NULL, 16);
106 }
Chia-I Wu73019ad2014-08-29 12:01:13 +0800107 }
Chia-I Wu1c527012014-08-23 14:57:35 +0800108
109 if (!p)
110 break;
111
112 env = p + 1;
113 }
114}
Jon Ashburn815bddd2014-10-16 15:48:50 -0600115
Chia-I Wud71ff552015-02-20 12:50:12 -0700116static void intel_instance_add_gpu(struct intel_instance *instance,
117 struct intel_gpu *gpu)
118{
119 gpu->next = instance->gpus;
120 instance->gpus = gpu;
121}
122
123static void intel_instance_remove_gpus(struct intel_instance *instance)
124{
125 struct intel_gpu *gpu = instance->gpus;
126
127 while (gpu) {
128 struct intel_gpu *next = gpu->next;
129
130 intel_gpu_destroy(gpu);
131 gpu = next;
132 }
133
134 instance->gpus = NULL;
135}
136
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700137static void intel_instance_destroy(struct intel_instance *instance)
Jon Ashburnfa836e02015-01-28 18:26:16 -0700138{
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800139 struct icd_instance *icd = instance->icd;
140
Chia-I Wud71ff552015-02-20 12:50:12 -0700141 intel_instance_remove_gpus(instance);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800142 icd_instance_free(icd, instance);
143
144 icd_instance_destroy(icd);
Jon Ashburnfa836e02015-01-28 18:26:16 -0700145}
146
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600147static VkResult intel_instance_create(
148 const VkInstanceCreateInfo* info,
Chia-I Wu69f40122015-10-26 21:10:41 +0800149 const VkAllocCallbacks* allocator,
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600150 struct intel_instance **pInstance)
Jon Ashburnfa836e02015-01-28 18:26:16 -0700151{
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700152 struct intel_instance *instance;
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800153 struct icd_instance *icd;
Jon Ashburn29669a42015-04-04 14:52:07 -0600154 uint32_t i;
Jon Ashburnfa836e02015-01-28 18:26:16 -0700155
156 intel_debug_init();
157
Chia-I Wu69f40122015-10-26 21:10:41 +0800158 icd = icd_instance_create(info->pAppInfo, allocator);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800159 if (!icd)
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600160 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700161
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800162 instance = icd_instance_alloc(icd, sizeof(*instance), 0,
Chia-I Wu69f40122015-10-26 21:10:41 +0800163 VK_SYSTEM_ALLOC_SCOPE_INSTANCE);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800164 if (!instance) {
165 icd_instance_destroy(icd);
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600166 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800167 }
168
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700169 memset(instance, 0, sizeof(*instance));
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600170 intel_handle_init(&instance->handle, VK_OBJECT_TYPE_INSTANCE, instance);
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700171
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800172 instance->icd = icd;
173
Chia-I Wu763a7492015-10-26 20:48:51 +0800174 for (i = 0; i < info->enabledExtensionNameCount; i++) {
175 const enum intel_global_ext_type ext =
176 intel_gpu_lookup_global_extension(
177 info->ppEnabledExtensionNames[i]);
Jon Ashburn29669a42015-04-04 14:52:07 -0600178
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600179 if (ext != INTEL_GLOBAL_EXT_INVALID) {
180 instance->global_exts[ext] = true;
181 } else {
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600182 /* Fail create if extensions are specified that
183 * ICD cannot satisfy. Loader will filter out extensions / layers
184 * not meant by the ICD.
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600185 */
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600186 icd_instance_destroy(icd);
187 intel_instance_destroy(instance);
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600188 return VK_ERROR_EXTENSION_NOT_PRESENT;
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600189 }
Jon Ashburn29669a42015-04-04 14:52:07 -0600190 }
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600191
192 /*
193 * This ICD does not support any layers.
194 */
Chia-I Wu763a7492015-10-26 20:48:51 +0800195 if (info->enabledLayerNameCount > 0) {
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600196 icd_instance_destroy(icd);
197 intel_instance_destroy(instance);
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600198 return VK_ERROR_LAYER_NOT_PRESENT;
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600199 }
200
201 *pInstance = instance;
202
203 return VK_SUCCESS;
Jon Ashburnfa836e02015-01-28 18:26:16 -0700204}
205
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600206enum intel_global_ext_type intel_gpu_lookup_global_extension(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600207 const char *extName)
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600208{
209 enum intel_global_ext_type type;
210
211 for (type = 0; type < ARRAY_SIZE(intel_global_exts); type++) {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600212 if (compare_vk_extension_properties(&intel_global_exts[type], extName))
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600213 break;
214 }
215
216 assert(type < INTEL_GLOBAL_EXT_COUNT || type == INTEL_GLOBAL_EXT_INVALID);
217
218 return type;
219}
220
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600221ICD_EXPORT VkResult VKAPI vkCreateInstance(
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600222 const VkInstanceCreateInfo* pCreateInfo,
Chia-I Wu69f40122015-10-26 21:10:41 +0800223 const VkAllocCallbacks* pAllocator,
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600224 VkInstance* pInstance)
Jon Ashburn349508d2015-01-26 14:51:40 -0700225{
Chia-I Wu69f40122015-10-26 21:10:41 +0800226 return intel_instance_create(pCreateInfo, pAllocator,
227 (struct intel_instance **) pInstance);
Jon Ashburn349508d2015-01-26 14:51:40 -0700228}
229
Mark Lobodzinski67b42b72015-09-07 13:59:43 -0600230ICD_EXPORT void VKAPI vkDestroyInstance(
Chia-I Wu69f40122015-10-26 21:10:41 +0800231 VkInstance pInstance,
232 const VkAllocCallbacks* pAllocator)
Jon Ashburn349508d2015-01-26 14:51:40 -0700233{
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700234 struct intel_instance *instance = intel_instance(pInstance);
235
236 intel_instance_destroy(instance);
Jon Ashburn349508d2015-01-26 14:51:40 -0700237}
238
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600239ICD_EXPORT VkResult VKAPI vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600240 const char* pLayerName,
Chia-I Wu763a7492015-10-26 20:48:51 +0800241 uint32_t* pPropertyCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600242 VkExtensionProperties* pProperties)
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600243{
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600244 uint32_t copy_size;
245
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600246 if (pProperties == NULL) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800247 *pPropertyCount = INTEL_GLOBAL_EXT_COUNT;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600248 return VK_SUCCESS;
249 }
250
Chia-I Wu763a7492015-10-26 20:48:51 +0800251 copy_size = *pPropertyCount < INTEL_GLOBAL_EXT_COUNT ? *pPropertyCount : INTEL_GLOBAL_EXT_COUNT;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600252 memcpy(pProperties, intel_global_exts, copy_size * sizeof(VkExtensionProperties));
Chia-I Wu763a7492015-10-26 20:48:51 +0800253 *pPropertyCount = copy_size;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600254 if (copy_size < INTEL_GLOBAL_EXT_COUNT) {
255 return VK_INCOMPLETE;
256 }
257
Tony Barbour426b9052015-06-24 16:06:58 -0600258 return VK_SUCCESS;
259}
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600260
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600261ICD_EXPORT VkResult VKAPI vkEnumerateInstanceLayerProperties(
Chia-I Wu763a7492015-10-26 20:48:51 +0800262 uint32_t* pPropertyCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600263 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600264{
Chia-I Wu763a7492015-10-26 20:48:51 +0800265 *pPropertyCount = 0;
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600266 return VK_SUCCESS;
267}
268
Jon Ashburn07b309a2015-04-15 11:31:12 -0600269ICD_EXPORT VkResult VKAPI vkEnumeratePhysicalDevices(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600270 VkInstance instance_,
271 uint32_t* pPhysicalDeviceCount,
272 VkPhysicalDevice* pPhysicalDevices)
Jon Ashburn349508d2015-01-26 14:51:40 -0700273{
Chia-I Wud71ff552015-02-20 12:50:12 -0700274 struct intel_instance *instance = intel_instance(instance_);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700275 struct icd_drm_device *devices, *dev;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600276 VkResult ret;
Jon Ashburn92e80132015-01-29 15:47:01 -0700277 uint32_t count;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700278
Jon Ashburn07b309a2015-04-15 11:31:12 -0600279 if (pPhysicalDevices == NULL) {
280 *pPhysicalDeviceCount = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600281 return VK_SUCCESS;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700282 }
283
Jon Ashburn07b309a2015-04-15 11:31:12 -0600284 intel_instance_remove_gpus(instance);
285
Chia-I Wu15517d82015-02-20 13:41:57 -0700286 devices = icd_drm_enumerate(instance->icd, 0x8086);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700287
288 count = 0;
289 dev = devices;
290 while (dev) {
291 const char *primary_node, *render_node;
292 int devid;
293 struct intel_gpu *gpu;
294
295 primary_node = icd_drm_get_devnode(dev, ICD_DRM_MINOR_LEGACY);
296 if (!primary_node)
297 continue;
298
299 render_node = icd_drm_get_devnode(dev, ICD_DRM_MINOR_RENDER);
300
301 devid = (intel_devid_override) ? intel_devid_override : dev->devid;
Chia-I Wud71ff552015-02-20 12:50:12 -0700302 ret = intel_gpu_create(instance, devid,
303 primary_node, render_node, &gpu);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600304 if (ret == VK_SUCCESS) {
Chia-I Wud71ff552015-02-20 12:50:12 -0700305 intel_instance_add_gpu(instance, gpu);
306
Tony Barbour8205d902015-04-16 15:59:00 -0600307 pPhysicalDevices[count++] = (VkPhysicalDevice) gpu;
Jon Ashburn07b309a2015-04-15 11:31:12 -0600308 if (count >= *pPhysicalDeviceCount)
Jon Ashburn5f078e92015-01-28 19:15:45 -0700309 break;
310 }
311
312 dev = dev->next;
313 }
314
Chia-I Wu15517d82015-02-20 13:41:57 -0700315 icd_drm_release(instance->icd, devices);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700316
Jon Ashburn07b309a2015-04-15 11:31:12 -0600317 *pPhysicalDeviceCount = count;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700318
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600319 return VK_SUCCESS;
Jon Ashburn349508d2015-01-26 14:51:40 -0700320}
321
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600322ICD_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
323 VkInstance instance,
324 VkFlags msgFlags,
325 PFN_vkDbgMsgCallback pfnMsgCallback,
326 void* pUserData,
327 VkDbgMsgCallback* pMsgCallback)
Chia-I Wub02558c2015-01-03 15:21:51 +0800328{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600329 struct intel_instance *inst = intel_instance(instance);
Courtney Goeltzenleuchter0629efa2015-04-13 14:59:19 -0600330
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600331 return icd_instance_create_logger(inst->icd, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Chia-I Wub02558c2015-01-03 15:21:51 +0800332}
333
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600334ICD_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
335 VkInstance instance,
336 VkDbgMsgCallback msgCallback)
Chia-I Wub02558c2015-01-03 15:21:51 +0800337{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600338 struct intel_instance *inst = intel_instance(instance);
Courtney Goeltzenleuchter0629efa2015-04-13 14:59:19 -0600339
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600340 return icd_instance_destroy_logger(inst->icd, msgCallback);
Chia-I Wub02558c2015-01-03 15:21:51 +0800341}