blob: 2cce88c2b00eb19dda30632c828acaa3eb9a527c [file] [log] [blame]
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06001/*
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06002 *
Courtney Goeltzenleuchter8a17da52015-10-29 13:50:34 -06003 * Copyright (C) 2015 Valve Corporation
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -06004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060023 * Author: Chia-I Wu <olv@lunarg.com>
24 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
25 *
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060026 */
27
Chia-I Wu023ef682014-09-15 11:06:50 +080028#include "icd-enumerate-drm.h"
Chia-I Wua6e33492014-08-05 13:35:08 +080029#include "gpu.h"
Chia-I Wu94ae71a2015-02-20 12:26:08 -070030#include "instance.h"
Courtney Goeltzenleuchtere06e72d2014-08-01 12:44:23 -060031
Chia-I Wu73019ad2014-08-29 12:01:13 +080032static int intel_devid_override;
Chia-I Wu1c527012014-08-23 14:57:35 +080033int intel_debug = -1;
34
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060035void *intel_alloc(const void *handle,
36 size_t size, size_t alignment,
Chia-I Wu1f851912015-10-27 18:04:07 +080037 VkSystemAllocationScope scope)
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060038{
39 assert(intel_handle_validate(handle));
40 return icd_instance_alloc(((const struct intel_handle *) handle)->instance->icd,
Chia-I Wu69f40122015-10-26 21:10:41 +080041 size, alignment, scope);
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060042}
43
44void intel_free(const void *handle, void *ptr)
45{
46 assert(intel_handle_validate(handle));
47 icd_instance_free(((const struct intel_handle *) handle)->instance->icd, ptr);
48}
49
50void intel_logv(const void *handle,
51 VkFlags msg_flags,
Tony Barbourde4124d2015-07-03 10:33:54 -060052 VkDbgObjectType obj_type, uint64_t src_object,
Courtney Goeltzenleuchter33a54d52015-06-09 07:50:24 -060053 size_t location, int32_t msg_code,
54 const char *format, va_list ap)
55{
56 char msg[256];
57 int ret;
58
59 ret = vsnprintf(msg, sizeof(msg), format, ap);
60 if (ret >= sizeof(msg) || ret < 0)
61 msg[sizeof(msg) - 1] = '\0';
62
63 assert(intel_handle_validate(handle));
64 icd_instance_log(((const struct intel_handle *) handle)->instance->icd,
65 msg_flags,
66 obj_type, src_object, /* obj_type, object */
67 location, msg_code, /* location, msg_code */
68 msg);
69}
70
Chia-I Wu1c527012014-08-23 14:57:35 +080071static void intel_debug_init(void)
72{
73 const char *env;
74
75 if (intel_debug >= 0)
76 return;
77
78 intel_debug = 0;
79
80 /* parse comma-separated debug options */
Courtney Goeltzenleuchter893f2872015-07-29 09:08:22 -060081 env = getenv("VK_INTEL_DEBUG");
Chia-I Wu1c527012014-08-23 14:57:35 +080082 while (env) {
83 const char *p = strchr(env, ',');
84 size_t len;
85
86 if (p)
87 len = p - env;
88 else
89 len = strlen(env);
90
Courtney Goeltzenleuchterd9fc9842014-10-13 12:58:25 -060091 if (len > 0) {
92 if (strncmp(env, "batch", len) == 0) {
93 intel_debug |= INTEL_DEBUG_BATCH;
94 } else if (strncmp(env, "nohw", len) == 0) {
95 intel_debug |= INTEL_DEBUG_NOHW;
Chia-I Wu3fb47ce2014-10-28 11:19:36 +080096 } else if (strncmp(env, "nocache", len) == 0) {
97 intel_debug |= INTEL_DEBUG_NOCACHE;
Chia-I Wuc45db532015-02-19 11:20:38 -070098 } else if (strncmp(env, "nohiz", len) == 0) {
99 intel_debug |= INTEL_DEBUG_NOHIZ;
Chia-I Wu465fe212015-02-11 11:27:06 -0700100 } else if (strncmp(env, "hang", len) == 0) {
101 intel_debug |= INTEL_DEBUG_HANG;
Courtney Goeltzenleuchterd9fc9842014-10-13 12:58:25 -0600102 } else if (strncmp(env, "0x", 2) == 0) {
103 intel_debug |= INTEL_DEBUG_NOHW;
104 intel_devid_override = strtol(env, NULL, 16);
105 }
Chia-I Wu73019ad2014-08-29 12:01:13 +0800106 }
Chia-I Wu1c527012014-08-23 14:57:35 +0800107
108 if (!p)
109 break;
110
111 env = p + 1;
112 }
113}
Jon Ashburn815bddd2014-10-16 15:48:50 -0600114
Chia-I Wud71ff552015-02-20 12:50:12 -0700115static void intel_instance_add_gpu(struct intel_instance *instance,
116 struct intel_gpu *gpu)
117{
118 gpu->next = instance->gpus;
119 instance->gpus = gpu;
120}
121
122static void intel_instance_remove_gpus(struct intel_instance *instance)
123{
124 struct intel_gpu *gpu = instance->gpus;
125
126 while (gpu) {
127 struct intel_gpu *next = gpu->next;
128
129 intel_gpu_destroy(gpu);
130 gpu = next;
131 }
132
133 instance->gpus = NULL;
134}
135
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700136static void intel_instance_destroy(struct intel_instance *instance)
Jon Ashburnfa836e02015-01-28 18:26:16 -0700137{
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800138 struct icd_instance *icd = instance->icd;
139
Chia-I Wud71ff552015-02-20 12:50:12 -0700140 intel_instance_remove_gpus(instance);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800141 icd_instance_free(icd, instance);
142
143 icd_instance_destroy(icd);
Jon Ashburnfa836e02015-01-28 18:26:16 -0700144}
145
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600146static VkResult intel_instance_create(
147 const VkInstanceCreateInfo* info,
Chia-I Wu1f851912015-10-27 18:04:07 +0800148 const VkAllocationCallbacks* allocator,
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600149 struct intel_instance **pInstance)
Jon Ashburnfa836e02015-01-28 18:26:16 -0700150{
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700151 struct intel_instance *instance;
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800152 struct icd_instance *icd;
Jon Ashburn29669a42015-04-04 14:52:07 -0600153 uint32_t i;
Jon Ashburnfa836e02015-01-28 18:26:16 -0700154
155 intel_debug_init();
156
Chia-I Wu1f851912015-10-27 18:04:07 +0800157 icd = icd_instance_create(info->pApplicationInfo, allocator);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800158 if (!icd)
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600159 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700160
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800161 instance = icd_instance_alloc(icd, sizeof(*instance), 0,
Chia-I Wu1f851912015-10-27 18:04:07 +0800162 VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800163 if (!instance) {
164 icd_instance_destroy(icd);
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600165 return VK_ERROR_OUT_OF_HOST_MEMORY;
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800166 }
167
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700168 memset(instance, 0, sizeof(*instance));
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600169 intel_handle_init(&instance->handle, VK_OBJECT_TYPE_INSTANCE, instance);
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700170
Chia-I Wu96a41bc2015-02-21 14:19:23 +0800171 instance->icd = icd;
172
Chia-I Wu763a7492015-10-26 20:48:51 +0800173 for (i = 0; i < info->enabledExtensionNameCount; i++) {
174 const enum intel_global_ext_type ext =
175 intel_gpu_lookup_global_extension(
176 info->ppEnabledExtensionNames[i]);
Jon Ashburn29669a42015-04-04 14:52:07 -0600177
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600178 if (ext != INTEL_GLOBAL_EXT_INVALID) {
179 instance->global_exts[ext] = true;
180 } else {
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600181 /* Fail create if extensions are specified that
182 * ICD cannot satisfy. Loader will filter out extensions / layers
183 * not meant by the ICD.
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600184 */
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600185 icd_instance_destroy(icd);
186 intel_instance_destroy(instance);
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600187 return VK_ERROR_EXTENSION_NOT_PRESENT;
Courtney Goeltzenleuchter9ecf6852015-06-09 08:22:48 -0600188 }
Jon Ashburn29669a42015-04-04 14:52:07 -0600189 }
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600190
191 /*
192 * This ICD does not support any layers.
193 */
Chia-I Wu763a7492015-10-26 20:48:51 +0800194 if (info->enabledLayerNameCount > 0) {
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600195 icd_instance_destroy(icd);
196 intel_instance_destroy(instance);
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600197 return VK_ERROR_LAYER_NOT_PRESENT;
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600198 }
199
200 *pInstance = instance;
201
202 return VK_SUCCESS;
Jon Ashburnfa836e02015-01-28 18:26:16 -0700203}
204
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600205enum intel_global_ext_type intel_gpu_lookup_global_extension(
Chia-I Wu1f851912015-10-27 18:04:07 +0800206 const char *extensionName)
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600207{
208 enum intel_global_ext_type type;
209
210 for (type = 0; type < ARRAY_SIZE(intel_global_exts); type++) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800211 if (compare_vk_extension_properties(&intel_global_exts[type], extensionName))
Courtney Goeltzenleuchter95b73722015-06-08 18:08:35 -0600212 break;
213 }
214
215 assert(type < INTEL_GLOBAL_EXT_COUNT || type == INTEL_GLOBAL_EXT_INVALID);
216
217 return type;
218}
219
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800220ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600221 const VkInstanceCreateInfo* pCreateInfo,
Chia-I Wu1f851912015-10-27 18:04:07 +0800222 const VkAllocationCallbacks* pAllocator,
Courtney Goeltzenleuchterb44d6f22015-07-05 22:09:41 -0600223 VkInstance* pInstance)
Jon Ashburn349508d2015-01-26 14:51:40 -0700224{
Chia-I Wu69f40122015-10-26 21:10:41 +0800225 return intel_instance_create(pCreateInfo, pAllocator,
226 (struct intel_instance **) pInstance);
Jon Ashburn349508d2015-01-26 14:51:40 -0700227}
228
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800229ICD_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(
Chia-I Wu69f40122015-10-26 21:10:41 +0800230 VkInstance pInstance,
Chia-I Wu1f851912015-10-27 18:04:07 +0800231 const VkAllocationCallbacks* pAllocator)
Jon Ashburn349508d2015-01-26 14:51:40 -0700232{
Chia-I Wu94ae71a2015-02-20 12:26:08 -0700233 struct intel_instance *instance = intel_instance(pInstance);
234
235 intel_instance_destroy(instance);
Jon Ashburn349508d2015-01-26 14:51:40 -0700236}
237
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800238ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600239 const char* pLayerName,
Chia-I Wu763a7492015-10-26 20:48:51 +0800240 uint32_t* pPropertyCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600241 VkExtensionProperties* pProperties)
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600242{
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600243 uint32_t copy_size;
244
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600245 if (pProperties == NULL) {
Chia-I Wu763a7492015-10-26 20:48:51 +0800246 *pPropertyCount = INTEL_GLOBAL_EXT_COUNT;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600247 return VK_SUCCESS;
248 }
249
Chia-I Wu763a7492015-10-26 20:48:51 +0800250 copy_size = *pPropertyCount < INTEL_GLOBAL_EXT_COUNT ? *pPropertyCount : INTEL_GLOBAL_EXT_COUNT;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600251 memcpy(pProperties, intel_global_exts, copy_size * sizeof(VkExtensionProperties));
Chia-I Wu763a7492015-10-26 20:48:51 +0800252 *pPropertyCount = copy_size;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600253 if (copy_size < INTEL_GLOBAL_EXT_COUNT) {
254 return VK_INCOMPLETE;
255 }
256
Tony Barbour426b9052015-06-24 16:06:58 -0600257 return VK_SUCCESS;
258}
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600259
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800260ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(
Chia-I Wu763a7492015-10-26 20:48:51 +0800261 uint32_t* pPropertyCount,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600262 VkLayerProperties* pProperties)
Tony Barbour426b9052015-06-24 16:06:58 -0600263{
Chia-I Wu763a7492015-10-26 20:48:51 +0800264 *pPropertyCount = 0;
Courtney Goeltzenleuchterf0441e62015-06-09 08:20:20 -0600265 return VK_SUCCESS;
266}
267
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800268ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600269 VkInstance instance_,
270 uint32_t* pPhysicalDeviceCount,
271 VkPhysicalDevice* pPhysicalDevices)
Jon Ashburn349508d2015-01-26 14:51:40 -0700272{
Chia-I Wud71ff552015-02-20 12:50:12 -0700273 struct intel_instance *instance = intel_instance(instance_);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700274 struct icd_drm_device *devices, *dev;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600275 VkResult ret;
Jon Ashburn92e80132015-01-29 15:47:01 -0700276 uint32_t count;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700277
Jon Ashburn07b309a2015-04-15 11:31:12 -0600278 if (pPhysicalDevices == NULL) {
279 *pPhysicalDeviceCount = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600280 return VK_SUCCESS;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700281 }
282
Jon Ashburn07b309a2015-04-15 11:31:12 -0600283 intel_instance_remove_gpus(instance);
284
Chia-I Wu15517d82015-02-20 13:41:57 -0700285 devices = icd_drm_enumerate(instance->icd, 0x8086);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700286
287 count = 0;
288 dev = devices;
289 while (dev) {
290 const char *primary_node, *render_node;
291 int devid;
292 struct intel_gpu *gpu;
293
294 primary_node = icd_drm_get_devnode(dev, ICD_DRM_MINOR_LEGACY);
295 if (!primary_node)
296 continue;
297
298 render_node = icd_drm_get_devnode(dev, ICD_DRM_MINOR_RENDER);
299
300 devid = (intel_devid_override) ? intel_devid_override : dev->devid;
Chia-I Wud71ff552015-02-20 12:50:12 -0700301 ret = intel_gpu_create(instance, devid,
302 primary_node, render_node, &gpu);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600303 if (ret == VK_SUCCESS) {
Chia-I Wud71ff552015-02-20 12:50:12 -0700304 intel_instance_add_gpu(instance, gpu);
305
Tony Barbour8205d902015-04-16 15:59:00 -0600306 pPhysicalDevices[count++] = (VkPhysicalDevice) gpu;
Jon Ashburn07b309a2015-04-15 11:31:12 -0600307 if (count >= *pPhysicalDeviceCount)
Jon Ashburn5f078e92015-01-28 19:15:45 -0700308 break;
309 }
310
311 dev = dev->next;
312 }
313
Chia-I Wu15517d82015-02-20 13:41:57 -0700314 icd_drm_release(instance->icd, devices);
Jon Ashburn5f078e92015-01-28 19:15:45 -0700315
Jon Ashburn07b309a2015-04-15 11:31:12 -0600316 *pPhysicalDeviceCount = count;
Jon Ashburn5f078e92015-01-28 19:15:45 -0700317
Courtney Goeltzenleuchterac544f32015-09-14 18:01:17 -0600318 return VK_SUCCESS;
Jon Ashburn349508d2015-01-26 14:51:40 -0700319}
320
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800321ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgCreateMsgCallback(
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600322 VkInstance instance,
323 VkFlags msgFlags,
324 PFN_vkDbgMsgCallback pfnMsgCallback,
325 void* pUserData,
326 VkDbgMsgCallback* pMsgCallback)
Chia-I Wub02558c2015-01-03 15:21:51 +0800327{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600328 struct intel_instance *inst = intel_instance(instance);
Courtney Goeltzenleuchter0629efa2015-04-13 14:59:19 -0600329
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600330 return icd_instance_create_logger(inst->icd, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
Chia-I Wub02558c2015-01-03 15:21:51 +0800331}
332
Chia-I Wuaf9e4fd2015-11-06 06:42:02 +0800333ICD_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkDbgDestroyMsgCallback(
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600334 VkInstance instance,
335 VkDbgMsgCallback msgCallback)
Chia-I Wub02558c2015-01-03 15:21:51 +0800336{
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600337 struct intel_instance *inst = intel_instance(instance);
Courtney Goeltzenleuchter0629efa2015-04-13 14:59:19 -0600338
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600339 return icd_instance_destroy_logger(inst->icd, msgCallback);
Chia-I Wub02558c2015-01-03 15:21:51 +0800340}