blob: 7c5034e87697952f647dbb5f984b5d08de722364 [file] [log] [blame]
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001/*
Jon Ashburn44aed662016-02-02 17:47:28 -07002 * Copyright (c) 2015-2016 The Khronos Group Inc.
3 * Copyright (c) 2015-2016 Valve Corporation
4 * Copyright (c) 2015-2016 LunarG, Inc.
5 * Copyright (C) 2015-2016 Google Inc.
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06006 *
Jon Ashburn44aed662016-02-02 17:47:28 -07007 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and/or associated documentation files (the "Materials"), to
9 * deal in the Materials without restriction, including without limitation the
10 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Materials, and to permit persons to whom the Materials are
12 * furnished to do so, subject to the following conditions:
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060013 *
Jon Ashburn44aed662016-02-02 17:47:28 -070014 * The above copyright notice(s) and this permission notice shall be included in
15 * all copies or substantial portions of the Materials.
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060016 *
Jon Ashburn44aed662016-02-02 17:47:28 -070017 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060018 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jon Ashburn44aed662016-02-02 17:47:28 -070019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 *
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
24 * USE OR OTHER DEALINGS IN THE MATERIALS.
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060025 *
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060026 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
Jon Ashburn44aed662016-02-02 17:47:28 -070027 * Author: Jon Ashburn <jon@LunarG.com>
Courtney Goeltzenleuchter96cd7952015-10-30 11:14:30 -060028 *
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060029 */
30
Courtney Goeltzenleuchterb620ace2015-07-05 11:28:29 -060031#define _GNU_SOURCE
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -060032#include <stdio.h>
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060033#include <string.h>
34#include <stdlib.h>
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -060035#include <inttypes.h>
Tony Barbour69698512015-06-18 16:29:32 -060036#ifndef WIN32
Courtney Goeltzenleuchterc3c1f012015-07-22 11:01:53 -060037#include <signal.h>
38#else
Tony Barbour69698512015-06-18 16:29:32 -060039#endif
Jon Ashburn6fb9a532015-08-28 14:58:46 -070040#include "vk_loader_platform.h"
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060041#include "debug_report.h"
David Pinedo329ca9e2015-11-06 12:54:48 -070042#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060043
Jon Ashburn44aed662016-02-02 17:47:28 -070044typedef void(VKAPI_PTR *PFN_stringCallback)(char *message);
Courtney Goeltzenleuchterf1eb2492015-06-11 16:01:11 -060045
Jon Ashburnc4748dc2015-08-04 11:14:18 -060046static const VkExtensionProperties debug_report_extension_info = {
Jon Ashburn44aed662016-02-02 17:47:28 -070047 .extensionName = VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
48 .specVersion = VK_EXT_DEBUG_REPORT_SPEC_VERSION,
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060049};
50
51void debug_report_add_instance_extensions(
Jon Ashburn44aed662016-02-02 17:47:28 -070052 const struct loader_instance *inst,
53 struct loader_extension_list *ext_list) {
Jon Ashburne58f1a32015-08-28 13:38:21 -060054 loader_add_to_ext_list(inst, ext_list, 1, &debug_report_extension_info);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060055}
56
Jon Ashburn44aed662016-02-02 17:47:28 -070057void debug_report_create_instance(struct loader_instance *ptr_instance,
58 const VkInstanceCreateInfo *pCreateInfo) {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -060059 ptr_instance->debug_report_enabled = false;
60
Jon Ashburna4ae48b2016-01-11 13:12:43 -070061 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Jon Ashburn44aed662016-02-02 17:47:28 -070062 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
63 VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -060064 ptr_instance->debug_report_enabled = true;
65 return;
66 }
67 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -060068}
69
Jon Ashburn44aed662016-02-02 17:47:28 -070070VkResult
71util_CreateDebugReportCallback(struct loader_instance *inst,
72 VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
73 const VkAllocationCallbacks *pAllocator,
74 VkDebugReportCallbackEXT callback) {
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -070075 VkLayerDbgFunctionNode *pNewDbgFuncNode;
76 if (pAllocator != NULL) {
Jon Ashburn44aed662016-02-02 17:47:28 -070077 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(
78 pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
79 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -070080 } else {
Jon Ashburn44aed662016-02-02 17:47:28 -070081 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_heap_alloc(
82 inst, sizeof(VkLayerDbgFunctionNode),
83 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -070084 }
85 if (!pNewDbgFuncNode)
86 return VK_ERROR_OUT_OF_HOST_MEMORY;
87
88 pNewDbgFuncNode->msgCallback = callback;
89 pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
90 pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
91 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
92 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
93 inst->DbgFunctionHead = pNewDbgFuncNode;
94
95 return VK_SUCCESS;
96}
97
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -070098static VKAPI_ATTR VkResult VKAPI_CALL debug_report_CreateDebugReportCallback(
Jon Ashburn44aed662016-02-02 17:47:28 -070099 VkInstance instance, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
100 VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
Jon Ashburn0c5eea22015-09-30 12:56:42 -0600101 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburnb40f2562015-05-29 13:15:39 -0600102 loader_platform_thread_lock_mutex(&loader_lock);
Jon Ashburn44aed662016-02-02 17:47:28 -0700103 VkResult result = inst->disp->CreateDebugReportCallbackEXT(
104 instance, pCreateInfo, pAllocator, pCallback);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600105 if (result == VK_SUCCESS) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700106 result = util_CreateDebugReportCallback(inst, pCreateInfo, pAllocator,
107 *pCallback);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600108 }
Jon Ashburnb40f2562015-05-29 13:15:39 -0600109 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600110 return result;
111}
112
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700113// Utility function to handle reporting
Jon Ashburn44aed662016-02-02 17:47:28 -0700114VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
115 VkFlags msgFlags,
116 VkDebugReportObjectTypeEXT objectType,
117 uint64_t srcObject, size_t location,
118 int32_t msgCode, const char *pLayerPrefix,
119 const char *pMsg) {
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700120 VkBool32 bail = false;
121 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
122 while (pTrav) {
123 if (pTrav->msgFlags & msgFlags) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700124 if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location,
125 msgCode, pLayerPrefix, pMsg,
126 pTrav->pUserData)) {
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700127 bail = true;
128 }
129 }
130 pTrav = pTrav->pNext;
131 }
132
133 return bail;
134}
135
Jon Ashburn44aed662016-02-02 17:47:28 -0700136void util_DestroyDebugReportCallback(struct loader_instance *inst,
137 VkDebugReportCallbackEXT callback,
138 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700139 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
140 VkLayerDbgFunctionNode *pPrev = pTrav;
141
142 while (pTrav) {
143 if (pTrav->msgCallback == callback) {
144 pPrev->pNext = pTrav->pNext;
145 if (inst->DbgFunctionHead == pTrav)
146 inst->DbgFunctionHead = pTrav->pNext;
147 if (pAllocator != NULL) {
148 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
149 } else {
150 loader_heap_free(inst, pTrav);
151 }
152 break;
153 }
154 pPrev = pTrav;
155 pTrav = pTrav->pNext;
156 }
157}
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700158
Ian Elliott01b78322016-03-31 10:48:19 -0600159// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
160// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
161// then allocates array that can hold that many structs, as well as that many
162// VkDebugReportCallbackEXT handles. It then copies each
163// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600164VkResult util_CopyDebugReportCreateInfos(
165 const void *pChain, const VkAllocationCallbacks *pAllocator,
166 uint32_t *num_callbacks, VkDebugReportCallbackCreateInfoEXT **infos,
167 VkDebugReportCallbackEXT **callbacks) {
Ian Elliott01b78322016-03-31 10:48:19 -0600168 uint32_t n = *num_callbacks = 0;
169
170 // NOTE: The loader is not using pAllocator, and so this function doesn't
171 // either.
172
173 const void *pNext = pChain;
174 while (pNext) {
175 // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
176 if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType ==
177 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
178 n++;
179 }
180 pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
181 }
182 if (n == 0) {
183 return VK_SUCCESS;
184 }
185
186 // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600187 VkDebugReportCallbackCreateInfoEXT *pInfos = *infos =
188 ((VkDebugReportCallbackCreateInfoEXT *)malloc(
189 n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
Ian Elliott01b78322016-03-31 10:48:19 -0600190 if (!pInfos) {
191 return VK_ERROR_OUT_OF_HOST_MEMORY;
192 }
193 // 3rd, allocate memory for a unique handle for each callback:
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600194 VkDebugReportCallbackEXT *pCallbacks = *callbacks =
195 ((VkDebugReportCallbackEXT *)malloc(n *
196 sizeof(VkDebugReportCallbackEXT)));
Ian Elliott01b78322016-03-31 10:48:19 -0600197 if (!pCallbacks) {
198 free(pInfos);
199 return VK_ERROR_OUT_OF_HOST_MEMORY;
200 }
201 // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
202 // vkDestroyInstance, and assign a unique handle to each callback (just
203 // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
204 pNext = pChain;
205 while (pNext) {
206 if (((VkInstanceCreateInfo *)pNext)->sType ==
207 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600208 memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
Ian Elliott01b78322016-03-31 10:48:19 -0600209 *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
210 }
211 pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
212 }
213
214 *num_callbacks = n;
215 return VK_SUCCESS;
216}
217
218void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
219 VkDebugReportCallbackCreateInfoEXT *infos,
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600220 VkDebugReportCallbackEXT *callbacks) {
Ian Elliott01b78322016-03-31 10:48:19 -0600221 free(infos);
222 free(callbacks);
223}
224
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600225VkResult util_CreateDebugReportCallbacks(
226 struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
227 uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
228 VkDebugReportCallbackEXT *callbacks) {
Jamie Madill1d5109d2016-04-04 15:09:51 -0400229 VkResult rtn = VK_SUCCESS;
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600230 for (uint32_t i = 0; i < num_callbacks; i++) {
231 rtn = util_CreateDebugReportCallback(inst, &infos[i], pAllocator,
Ian Elliott01b78322016-03-31 10:48:19 -0600232 callbacks[i]);
233 if (rtn != VK_SUCCESS) {
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600234 for (uint32_t j = 0; j < i; j++) {
235 util_DestroyDebugReportCallback(inst, callbacks[j], pAllocator);
Ian Elliott01b78322016-03-31 10:48:19 -0600236 }
237 return rtn;
238 }
239 }
240 return rtn;
241}
242
243void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
244 const VkAllocationCallbacks *pAllocator,
245 uint32_t num_callbacks,
Jon Ashburn9b2a8c92016-04-15 09:25:03 -0600246 VkDebugReportCallbackEXT *callbacks) {
247 for (uint32_t i = 0; i < num_callbacks; i++) {
248 util_DestroyDebugReportCallback(inst, callbacks[i], pAllocator);
Ian Elliott01b78322016-03-31 10:48:19 -0600249 }
250}
251
Jon Ashburn44aed662016-02-02 17:47:28 -0700252static VKAPI_ATTR void VKAPI_CALL
253debug_report_DestroyDebugReportCallback(VkInstance instance,
254 VkDebugReportCallbackEXT callback,
255 VkAllocationCallbacks *pAllocator) {
Jon Ashburn0c5eea22015-09-30 12:56:42 -0600256 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburnb40f2562015-05-29 13:15:39 -0600257 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600258
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700259 inst->disp->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600260
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700261 util_DestroyDebugReportCallback(inst, callback, pAllocator);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600262
Jon Ashburnb40f2562015-05-29 13:15:39 -0600263 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600264}
265
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700266static VKAPI_ATTR void VKAPI_CALL debug_report_DebugReportMessage(
Jon Ashburn44aed662016-02-02 17:47:28 -0700267 VkInstance instance, VkDebugReportFlagsEXT flags,
268 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
269 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700270 struct loader_instance *inst = loader_get_instance(instance);
271
Jon Ashburn44aed662016-02-02 17:47:28 -0700272 inst->disp->DebugReportMessageEXT(instance, flags, objType, object,
273 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700274}
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600275
276/*
277 * This is the instance chain terminator function
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -0700278 * for CreateDebugReportCallback
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600279 */
Tony Barbourde4124d2015-07-03 10:33:54 -0600280
Jon Ashburna9c4a572016-02-26 13:14:27 -0700281VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallback(
Jon Ashburn44aed662016-02-02 17:47:28 -0700282 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
283 const VkAllocationCallbacks *pAllocator,
284 VkDebugReportCallbackEXT *pCallback) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700285 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600286 const struct loader_icd *icd;
Jon Ashburn44aed662016-02-02 17:47:28 -0700287 struct loader_instance *inst = (struct loader_instance *)instance;
Karl Schultzc50a5982016-02-24 14:39:39 -0700288 VkResult res = VK_SUCCESS;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600289 uint32_t storage_idx;
290
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700291 icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600292 if (!icd_info) {
293 return VK_ERROR_OUT_OF_HOST_MEMORY;
294 }
295
296 storage_idx = 0;
297 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700298 if (!icd->CreateDebugReportCallbackEXT) {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600299 continue;
300 }
301
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700302 res = icd->CreateDebugReportCallbackEXT(
Jon Ashburn44aed662016-02-02 17:47:28 -0700303 icd->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600304
305 if (res != VK_SUCCESS) {
306 break;
307 }
308 storage_idx++;
309 }
310
311 /* roll back on errors */
312 if (icd) {
313 storage_idx = 0;
314 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue420a332015-10-26 20:04:44 +0800315 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700316 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn44aed662016-02-02 17:47:28 -0700317 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600318 }
319 storage_idx++;
320 }
321
322 return res;
323 }
324
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700325 *(VkDebugReportCallbackEXT **)pCallback = icd_info;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600326
327 return VK_SUCCESS;
328}
329
330/*
331 * This is the instance chain terminator function
Courtney Goeltzenleuchterf6a6e222015-11-30 12:13:14 -0700332 * for DestroyDebugReportCallback
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600333 */
Jon Ashburn44aed662016-02-02 17:47:28 -0700334VKAPI_ATTR void VKAPI_CALL
Jon Ashburna9c4a572016-02-26 13:14:27 -0700335terminator_DestroyDebugReportCallback(VkInstance instance,
336 VkDebugReportCallbackEXT callback,
337 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600338 uint32_t storage_idx;
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700339 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600340 const struct loader_icd *icd;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600341
Jon Ashburn44aed662016-02-02 17:47:28 -0700342 struct loader_instance *inst = (struct loader_instance *)instance;
343 icd_info = *(VkDebugReportCallbackEXT **)&callback;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600344 storage_idx = 0;
345 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue420a332015-10-26 20:04:44 +0800346 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700347 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn44aed662016-02-02 17:47:28 -0700348 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600349 }
350 storage_idx++;
351 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600352}
353
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700354/*
355 * This is the instance chain terminator function
356 * for DebugReportMessage
357 */
Jon Ashburn44aed662016-02-02 17:47:28 -0700358VKAPI_ATTR void VKAPI_CALL
Jon Ashburna9c4a572016-02-26 13:14:27 -0700359terminator_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags,
360 VkDebugReportObjectTypeEXT objType,
361 uint64_t object, size_t location, int32_t msgCode,
362 const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700363 const struct loader_icd *icd;
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700364
Jon Ashburn44aed662016-02-02 17:47:28 -0700365 struct loader_instance *inst = (struct loader_instance *)instance;
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700366
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700367 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700368 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700369 if (icd->DebugReportMessageEXT != NULL) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700370 icd->DebugReportMessageEXT(icd->instance, flags, objType, object,
371 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700372 }
373 }
374
375 /*
376 * Now that all ICDs have seen the message, call the necessary callbacks.
Jon Ashburn44aed662016-02-02 17:47:28 -0700377 * Ignoring "bail" return value as there is nothing to bail from at this
378 * point.
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700379 */
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700380
Jon Ashburn44aed662016-02-02 17:47:28 -0700381 util_DebugReportMessage(inst, flags, objType, object, location, msgCode,
382 pLayerPrefix, pMsg);
Courtney Goeltzenleuchter15436c12015-12-02 15:29:33 -0700383
384 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700385}
386
Jon Ashburn44aed662016-02-02 17:47:28 -0700387bool debug_report_instance_gpa(struct loader_instance *ptr_instance,
388 const char *name, void **addr) {
Jon Ashburn99456002015-11-06 11:02:40 -0700389 // debug_report is currently advertised to be supported by the loader,
390 // so always return the entry points if name matches and it's enabled
Jon Ashburn05b4ec62015-10-01 12:03:17 -0600391 *addr = NULL;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600392
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700393 if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700394 *addr = ptr_instance->debug_report_enabled
395 ? (void *)debug_report_CreateDebugReportCallback
396 : NULL;
Jon Ashburn05b4ec62015-10-01 12:03:17 -0600397 return true;
398 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700399 if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700400 *addr = ptr_instance->debug_report_enabled
401 ? (void *)debug_report_DestroyDebugReportCallback
402 : NULL;
Jon Ashburn05b4ec62015-10-01 12:03:17 -0600403 return true;
404 }
Courtney Goeltzenleuchteracb13592015-12-09 15:48:16 -0700405 if (!strcmp("vkDebugReportMessageEXT", name)) {
Jon Ashburn44aed662016-02-02 17:47:28 -0700406 *addr = ptr_instance->debug_report_enabled
407 ? (void *)debug_report_DebugReportMessage
408 : NULL;
Courtney Goeltzenleuchter6175e4b2015-11-30 15:28:25 -0700409 return true;
410 }
Jon Ashburn05b4ec62015-10-01 12:03:17 -0600411 return false;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600412}