blob: 4da1413a0400612fe30f17cd8e5191dd2dd52d65 [file] [log] [blame]
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -06001/*
Jon Ashburn23d36b12016-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 Goeltzenleuchterf579fa62015-06-10 17:39:03 -06006 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06007 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060010 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060011 * http://www.apache.org/licenses/LICENSE-2.0
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060012 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060013 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060018 *
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060019 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
Jon Ashburn23d36b12016-02-02 17:47:28 -070020 * Author: Jon Ashburn <jon@LunarG.com>
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060021 *
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060022 */
23
Courtney Goeltzenleuchter7f5aafc2015-07-05 11:28:29 -060024#define _GNU_SOURCE
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060025#include <stdio.h>
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060026#include <string.h>
27#include <stdlib.h>
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060028#include <inttypes.h>
Tony Barbour1d825c72015-06-18 16:29:32 -060029#ifndef WIN32
Courtney Goeltzenleuchter03663d02015-07-22 11:01:53 -060030#include <signal.h>
31#else
Tony Barbour1d825c72015-06-18 16:29:32 -060032#endif
Jon Ashburn480a50a2015-08-28 14:58:46 -070033#include "vk_loader_platform.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060034#include "debug_report.h"
David Pinedo9316d3b2015-11-06 12:54:48 -070035#include "vulkan/vk_layer.h"
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060036
Jon Ashburn23d36b12016-02-02 17:47:28 -070037typedef void(VKAPI_PTR *PFN_stringCallback)(char *message);
Courtney Goeltzenleuchter7dcc6a72015-06-11 16:01:11 -060038
Jon Ashburn5c042ea2015-08-04 11:14:18 -060039static const VkExtensionProperties debug_report_extension_info = {
Jon Ashburn23d36b12016-02-02 17:47:28 -070040 .extensionName = VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
41 .specVersion = VK_EXT_DEBUG_REPORT_SPEC_VERSION,
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060042};
43
44void debug_report_add_instance_extensions(
Jon Ashburn23d36b12016-02-02 17:47:28 -070045 const struct loader_instance *inst,
46 struct loader_extension_list *ext_list) {
Jon Ashburne39a4f82015-08-28 13:38:21 -060047 loader_add_to_ext_list(inst, ext_list, 1, &debug_report_extension_info);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060048}
49
Jon Ashburn23d36b12016-02-02 17:47:28 -070050void debug_report_create_instance(struct loader_instance *ptr_instance,
51 const VkInstanceCreateInfo *pCreateInfo) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060052 ptr_instance->debug_report_enabled = false;
53
Jon Ashburnf19916e2016-01-11 13:12:43 -070054 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
Jon Ashburn23d36b12016-02-02 17:47:28 -070055 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
56 VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -060057 ptr_instance->debug_report_enabled = true;
58 return;
59 }
60 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060061}
62
Jon Ashburn23d36b12016-02-02 17:47:28 -070063VkResult
64util_CreateDebugReportCallback(struct loader_instance *inst,
65 VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
66 const VkAllocationCallbacks *pAllocator,
67 VkDebugReportCallbackEXT callback) {
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070068 VkLayerDbgFunctionNode *pNewDbgFuncNode;
Mark Young0ad83132016-06-30 13:02:42 -060069#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
70 {
71#else
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070072 if (pAllocator != NULL) {
Jon Ashburn23d36b12016-02-02 17:47:28 -070073 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(
74 pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
Mark Young0ad83132016-06-30 13:02:42 -060075 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070076 } else {
Mark Young0ad83132016-06-30 13:02:42 -060077#endif
78 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(
Jon Ashburn23d36b12016-02-02 17:47:28 -070079 inst, sizeof(VkLayerDbgFunctionNode),
80 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070081 }
82 if (!pNewDbgFuncNode)
83 return VK_ERROR_OUT_OF_HOST_MEMORY;
84
85 pNewDbgFuncNode->msgCallback = callback;
86 pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
87 pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
88 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
89 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
90 inst->DbgFunctionHead = pNewDbgFuncNode;
91
92 return VK_SUCCESS;
93}
94
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -070095static VKAPI_ATTR VkResult VKAPI_CALL debug_report_CreateDebugReportCallback(
Jon Ashburn23d36b12016-02-02 17:47:28 -070096 VkInstance instance, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
97 VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
Jon Ashburne0e64572015-09-30 12:56:42 -060098 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -060099 loader_platform_thread_lock_mutex(&loader_lock);
Jon Ashburn23d36b12016-02-02 17:47:28 -0700100 VkResult result = inst->disp->CreateDebugReportCallbackEXT(
101 instance, pCreateInfo, pAllocator, pCallback);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600102 if (result == VK_SUCCESS) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700103 result = util_CreateDebugReportCallback(inst, pCreateInfo, pAllocator,
104 *pCallback);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600105 }
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600106 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600107 return result;
108}
109
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700110// Utility function to handle reporting
Jon Ashburn23d36b12016-02-02 17:47:28 -0700111VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
112 VkFlags msgFlags,
113 VkDebugReportObjectTypeEXT objectType,
114 uint64_t srcObject, size_t location,
115 int32_t msgCode, const char *pLayerPrefix,
116 const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700117 VkBool32 bail = false;
118 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
119 while (pTrav) {
120 if (pTrav->msgFlags & msgFlags) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700121 if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location,
122 msgCode, pLayerPrefix, pMsg,
123 pTrav->pUserData)) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700124 bail = true;
125 }
126 }
127 pTrav = pTrav->pNext;
128 }
129
130 return bail;
131}
132
Jon Ashburn23d36b12016-02-02 17:47:28 -0700133void util_DestroyDebugReportCallback(struct loader_instance *inst,
134 VkDebugReportCallbackEXT callback,
135 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700136 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
137 VkLayerDbgFunctionNode *pPrev = pTrav;
138
139 while (pTrav) {
140 if (pTrav->msgCallback == callback) {
141 pPrev->pNext = pTrav->pNext;
142 if (inst->DbgFunctionHead == pTrav)
143 inst->DbgFunctionHead = pTrav->pNext;
Mark Young0ad83132016-06-30 13:02:42 -0600144#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
145 {
146#else
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700147 if (pAllocator != NULL) {
148 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
149 } else {
Mark Young0ad83132016-06-30 13:02:42 -0600150#endif
151 loader_instance_heap_free(inst, pTrav);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700152 }
153 break;
154 }
155 pPrev = pTrav;
156 pTrav = pTrav->pNext;
157 }
158}
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700159
Ian Elliottad6300f2016-03-31 10:48:19 -0600160// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
161// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
162// then allocates array that can hold that many structs, as well as that many
163// VkDebugReportCallbackEXT handles. It then copies each
164// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
Jon Ashburncc407a22016-04-15 09:25:03 -0600165VkResult util_CopyDebugReportCreateInfos(
166 const void *pChain, const VkAllocationCallbacks *pAllocator,
167 uint32_t *num_callbacks, VkDebugReportCallbackCreateInfoEXT **infos,
168 VkDebugReportCallbackEXT **callbacks) {
Ian Elliottad6300f2016-03-31 10:48:19 -0600169 uint32_t n = *num_callbacks = 0;
Mark Young0ad83132016-06-30 13:02:42 -0600170 VkDebugReportCallbackCreateInfoEXT *pInfos = NULL;
171 VkDebugReportCallbackEXT *pCallbacks = NULL;
Ian Elliottad6300f2016-03-31 10:48:19 -0600172
173 // NOTE: The loader is not using pAllocator, and so this function doesn't
174 // either.
175
176 const void *pNext = pChain;
177 while (pNext) {
178 // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
179 if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType ==
180 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
181 n++;
182 }
183 pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
184 }
185 if (n == 0) {
186 return VK_SUCCESS;
187 }
188
Mark Young0ad83132016-06-30 13:02:42 -0600189// 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
190#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
191 {
192#else
193 if (pAllocator != NULL) {
194 pInfos = *infos =
195 ((VkDebugReportCallbackCreateInfoEXT *)pAllocator->pfnAllocation(
196 pAllocator->pUserData,
197 n * sizeof(VkDebugReportCallbackCreateInfoEXT), sizeof(void *),
198 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
199 } else {
200#endif
201 pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)malloc(
Jon Ashburncc407a22016-04-15 09:25:03 -0600202 n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
Mark Young0ad83132016-06-30 13:02:42 -0600203 }
Ian Elliottad6300f2016-03-31 10:48:19 -0600204 if (!pInfos) {
205 return VK_ERROR_OUT_OF_HOST_MEMORY;
206 }
Mark Young0ad83132016-06-30 13:02:42 -0600207// 3rd, allocate memory for a unique handle for each callback:
208#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
209 {
210#else
211 if (pAllocator != NULL) {
212 pCallbacks = *callbacks =
213 ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
214 pAllocator->pUserData, n * sizeof(VkDebugReportCallbackEXT),
215 sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
216 } else {
217#endif
218 pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(
219 n * sizeof(VkDebugReportCallbackEXT)));
220 }
Ian Elliottad6300f2016-03-31 10:48:19 -0600221 if (!pCallbacks) {
222 free(pInfos);
223 return VK_ERROR_OUT_OF_HOST_MEMORY;
224 }
225 // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
226 // vkDestroyInstance, and assign a unique handle to each callback (just
227 // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
228 pNext = pChain;
229 while (pNext) {
230 if (((VkInstanceCreateInfo *)pNext)->sType ==
231 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
Jon Ashburncc407a22016-04-15 09:25:03 -0600232 memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
Ian Elliottad6300f2016-03-31 10:48:19 -0600233 *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
234 }
235 pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
236 }
237
238 *num_callbacks = n;
239 return VK_SUCCESS;
240}
241
242void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
243 VkDebugReportCallbackCreateInfoEXT *infos,
Jon Ashburncc407a22016-04-15 09:25:03 -0600244 VkDebugReportCallbackEXT *callbacks) {
Ian Elliottad6300f2016-03-31 10:48:19 -0600245 free(infos);
246 free(callbacks);
247}
248
Jon Ashburncc407a22016-04-15 09:25:03 -0600249VkResult util_CreateDebugReportCallbacks(
250 struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
251 uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
252 VkDebugReportCallbackEXT *callbacks) {
Jamie Madill2b6b8d52016-04-04 15:09:51 -0400253 VkResult rtn = VK_SUCCESS;
Jon Ashburncc407a22016-04-15 09:25:03 -0600254 for (uint32_t i = 0; i < num_callbacks; i++) {
255 rtn = util_CreateDebugReportCallback(inst, &infos[i], pAllocator,
Ian Elliottad6300f2016-03-31 10:48:19 -0600256 callbacks[i]);
257 if (rtn != VK_SUCCESS) {
Jon Ashburncc407a22016-04-15 09:25:03 -0600258 for (uint32_t j = 0; j < i; j++) {
259 util_DestroyDebugReportCallback(inst, callbacks[j], pAllocator);
Ian Elliottad6300f2016-03-31 10:48:19 -0600260 }
261 return rtn;
262 }
263 }
264 return rtn;
265}
266
267void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
268 const VkAllocationCallbacks *pAllocator,
269 uint32_t num_callbacks,
Jon Ashburncc407a22016-04-15 09:25:03 -0600270 VkDebugReportCallbackEXT *callbacks) {
271 for (uint32_t i = 0; i < num_callbacks; i++) {
272 util_DestroyDebugReportCallback(inst, callbacks[i], pAllocator);
Ian Elliottad6300f2016-03-31 10:48:19 -0600273 }
274}
275
Jon Ashburn23d36b12016-02-02 17:47:28 -0700276static VKAPI_ATTR void VKAPI_CALL
277debug_report_DestroyDebugReportCallback(VkInstance instance,
278 VkDebugReportCallbackEXT callback,
279 VkAllocationCallbacks *pAllocator) {
Jon Ashburne0e64572015-09-30 12:56:42 -0600280 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600281 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600282
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700283 inst->disp->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600284
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700285 util_DestroyDebugReportCallback(inst, callback, pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600286
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600287 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600288}
289
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700290static VKAPI_ATTR void VKAPI_CALL debug_report_DebugReportMessage(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700291 VkInstance instance, VkDebugReportFlagsEXT flags,
292 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
293 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700294 struct loader_instance *inst = loader_get_instance(instance);
295
Jon Ashburn23d36b12016-02-02 17:47:28 -0700296 inst->disp->DebugReportMessageEXT(instance, flags, objType, object,
297 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700298}
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600299
300/*
301 * This is the instance chain terminator function
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700302 * for CreateDebugReportCallback
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600303 */
Tony Barbour1d2cd3f2015-07-03 10:33:54 -0600304
Jon Ashburn1530c342016-02-26 13:14:27 -0700305VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallback(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700306 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
307 const VkAllocationCallbacks *pAllocator,
308 VkDebugReportCallbackEXT *pCallback) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700309 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600310 const struct loader_icd *icd;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700311 struct loader_instance *inst = (struct loader_instance *)instance;
Karl Schultz2558bd32016-02-24 14:39:39 -0700312 VkResult res = VK_SUCCESS;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600313 uint32_t storage_idx;
314
Mark Young0ad83132016-06-30 13:02:42 -0600315#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
316 {
317#else
318 if (pAllocator != NULL) {
319 icd_info = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
320 pAllocator->pUserData,
321 inst->total_icd_count * sizeof(VkDebugReportCallbackEXT),
322 sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
323 memset(icd_info, 0,
324 inst->total_icd_count * sizeof(VkDebugReportCallbackEXT));
325 } else {
326#endif
327 icd_info =
328 calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
329 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600330 if (!icd_info) {
331 return VK_ERROR_OUT_OF_HOST_MEMORY;
332 }
333
334 storage_idx = 0;
335 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700336 if (!icd->CreateDebugReportCallbackEXT) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600337 continue;
338 }
339
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700340 res = icd->CreateDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700341 icd->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600342
343 if (res != VK_SUCCESS) {
344 break;
345 }
346 storage_idx++;
347 }
348
349 /* roll back on errors */
350 if (icd) {
351 storage_idx = 0;
352 for (icd = inst->icds; icd; icd = icd->next) {
Mark Younga26d47c2016-05-04 16:44:10 -0600353 if (NULL == icd->DestroyDebugReportCallbackEXT) {
354 continue;
355 }
356
Chia-I Wue2fc5522015-10-26 20:04:44 +0800357 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700358 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700359 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600360 }
361 storage_idx++;
362 }
363
364 return res;
365 }
366
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700367 *(VkDebugReportCallbackEXT **)pCallback = icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600368
369 return VK_SUCCESS;
370}
371
372/*
373 * This is the instance chain terminator function
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700374 * for DestroyDebugReportCallback
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600375 */
Mark Young0ad83132016-06-30 13:02:42 -0600376VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallback(
377 VkInstance instance, VkDebugReportCallbackEXT callback,
378 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600379 uint32_t storage_idx;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700380 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600381 const struct loader_icd *icd;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600382
Jon Ashburn23d36b12016-02-02 17:47:28 -0700383 struct loader_instance *inst = (struct loader_instance *)instance;
384 icd_info = *(VkDebugReportCallbackEXT **)&callback;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600385 storage_idx = 0;
386 for (icd = inst->icds; icd; icd = icd->next) {
Mark Younga26d47c2016-05-04 16:44:10 -0600387 if (NULL == icd->DestroyDebugReportCallbackEXT) {
388 continue;
389 }
390
Chia-I Wue2fc5522015-10-26 20:04:44 +0800391 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700392 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700393 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600394 }
395 storage_idx++;
396 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600397}
398
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700399/*
400 * This is the instance chain terminator function
401 * for DebugReportMessage
402 */
Mark Young0ad83132016-06-30 13:02:42 -0600403VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessage(
404 VkInstance instance, VkDebugReportFlagsEXT flags,
405 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
406 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700407 const struct loader_icd *icd;
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700408
Jon Ashburn23d36b12016-02-02 17:47:28 -0700409 struct loader_instance *inst = (struct loader_instance *)instance;
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700410
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700411 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700412 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700413 if (icd->DebugReportMessageEXT != NULL) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700414 icd->DebugReportMessageEXT(icd->instance, flags, objType, object,
415 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700416 }
417 }
418
419 /*
420 * Now that all ICDs have seen the message, call the necessary callbacks.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700421 * Ignoring "bail" return value as there is nothing to bail from at this
422 * point.
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700423 */
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700424
Jon Ashburn23d36b12016-02-02 17:47:28 -0700425 util_DebugReportMessage(inst, flags, objType, object, location, msgCode,
426 pLayerPrefix, pMsg);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700427
428 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700429}
430
Jon Ashburn23d36b12016-02-02 17:47:28 -0700431bool debug_report_instance_gpa(struct loader_instance *ptr_instance,
432 const char *name, void **addr) {
Jon Ashburn8a39efc2015-11-06 11:02:40 -0700433 // debug_report is currently advertised to be supported by the loader,
434 // so always return the entry points if name matches and it's enabled
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600435 *addr = NULL;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600436
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700437 if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700438 *addr = ptr_instance->debug_report_enabled
439 ? (void *)debug_report_CreateDebugReportCallback
440 : NULL;
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600441 return true;
442 }
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700443 if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700444 *addr = ptr_instance->debug_report_enabled
445 ? (void *)debug_report_DestroyDebugReportCallback
446 : NULL;
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600447 return true;
448 }
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700449 if (!strcmp("vkDebugReportMessageEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700450 *addr = ptr_instance->debug_report_enabled
451 ? (void *)debug_report_DebugReportMessage
452 : NULL;
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700453 return true;
454 }
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600455 return false;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600456}