blob: ae9b3ddf759688efcb3353eda1b482bbfbc8f104 [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;
69 if (pAllocator != NULL) {
Jon Ashburn23d36b12016-02-02 17:47:28 -070070 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(
71 pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
72 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070073 } else {
Jon Ashburn23d36b12016-02-02 17:47:28 -070074 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_heap_alloc(
75 inst, sizeof(VkLayerDbgFunctionNode),
76 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -070077 }
78 if (!pNewDbgFuncNode)
79 return VK_ERROR_OUT_OF_HOST_MEMORY;
80
81 pNewDbgFuncNode->msgCallback = callback;
82 pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
83 pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
84 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
85 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
86 inst->DbgFunctionHead = pNewDbgFuncNode;
87
88 return VK_SUCCESS;
89}
90
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -070091static VKAPI_ATTR VkResult VKAPI_CALL debug_report_CreateDebugReportCallback(
Jon Ashburn23d36b12016-02-02 17:47:28 -070092 VkInstance instance, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
93 VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
Jon Ashburne0e64572015-09-30 12:56:42 -060094 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -060095 loader_platform_thread_lock_mutex(&loader_lock);
Jon Ashburn23d36b12016-02-02 17:47:28 -070096 VkResult result = inst->disp->CreateDebugReportCallbackEXT(
97 instance, pCreateInfo, pAllocator, pCallback);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -060098 if (result == VK_SUCCESS) {
Jon Ashburn23d36b12016-02-02 17:47:28 -070099 result = util_CreateDebugReportCallback(inst, pCreateInfo, pAllocator,
100 *pCallback);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600101 }
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600102 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600103 return result;
104}
105
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700106// Utility function to handle reporting
Jon Ashburn23d36b12016-02-02 17:47:28 -0700107VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
108 VkFlags msgFlags,
109 VkDebugReportObjectTypeEXT objectType,
110 uint64_t srcObject, size_t location,
111 int32_t msgCode, const char *pLayerPrefix,
112 const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700113 VkBool32 bail = false;
114 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
115 while (pTrav) {
116 if (pTrav->msgFlags & msgFlags) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700117 if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location,
118 msgCode, pLayerPrefix, pMsg,
119 pTrav->pUserData)) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700120 bail = true;
121 }
122 }
123 pTrav = pTrav->pNext;
124 }
125
126 return bail;
127}
128
Jon Ashburn23d36b12016-02-02 17:47:28 -0700129void util_DestroyDebugReportCallback(struct loader_instance *inst,
130 VkDebugReportCallbackEXT callback,
131 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700132 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
133 VkLayerDbgFunctionNode *pPrev = pTrav;
134
135 while (pTrav) {
136 if (pTrav->msgCallback == callback) {
137 pPrev->pNext = pTrav->pNext;
138 if (inst->DbgFunctionHead == pTrav)
139 inst->DbgFunctionHead = pTrav->pNext;
140 if (pAllocator != NULL) {
141 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
142 } else {
143 loader_heap_free(inst, pTrav);
144 }
145 break;
146 }
147 pPrev = pTrav;
148 pTrav = pTrav->pNext;
149 }
150}
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700151
Ian Elliottad6300f2016-03-31 10:48:19 -0600152// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
153// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
154// then allocates array that can hold that many structs, as well as that many
155// VkDebugReportCallbackEXT handles. It then copies each
156// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
Jon Ashburncc407a22016-04-15 09:25:03 -0600157VkResult util_CopyDebugReportCreateInfos(
158 const void *pChain, const VkAllocationCallbacks *pAllocator,
159 uint32_t *num_callbacks, VkDebugReportCallbackCreateInfoEXT **infos,
160 VkDebugReportCallbackEXT **callbacks) {
Ian Elliottad6300f2016-03-31 10:48:19 -0600161 uint32_t n = *num_callbacks = 0;
162
163 // NOTE: The loader is not using pAllocator, and so this function doesn't
164 // either.
165
166 const void *pNext = pChain;
167 while (pNext) {
168 // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
169 if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType ==
170 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
171 n++;
172 }
173 pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
174 }
175 if (n == 0) {
176 return VK_SUCCESS;
177 }
178
179 // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
Jon Ashburncc407a22016-04-15 09:25:03 -0600180 VkDebugReportCallbackCreateInfoEXT *pInfos = *infos =
181 ((VkDebugReportCallbackCreateInfoEXT *)malloc(
182 n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
Ian Elliottad6300f2016-03-31 10:48:19 -0600183 if (!pInfos) {
184 return VK_ERROR_OUT_OF_HOST_MEMORY;
185 }
186 // 3rd, allocate memory for a unique handle for each callback:
Jon Ashburncc407a22016-04-15 09:25:03 -0600187 VkDebugReportCallbackEXT *pCallbacks = *callbacks =
188 ((VkDebugReportCallbackEXT *)malloc(n *
189 sizeof(VkDebugReportCallbackEXT)));
Ian Elliottad6300f2016-03-31 10:48:19 -0600190 if (!pCallbacks) {
191 free(pInfos);
192 return VK_ERROR_OUT_OF_HOST_MEMORY;
193 }
194 // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
195 // vkDestroyInstance, and assign a unique handle to each callback (just
196 // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
197 pNext = pChain;
198 while (pNext) {
199 if (((VkInstanceCreateInfo *)pNext)->sType ==
200 VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
Jon Ashburncc407a22016-04-15 09:25:03 -0600201 memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
Ian Elliottad6300f2016-03-31 10:48:19 -0600202 *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
203 }
204 pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
205 }
206
207 *num_callbacks = n;
208 return VK_SUCCESS;
209}
210
211void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
212 VkDebugReportCallbackCreateInfoEXT *infos,
Jon Ashburncc407a22016-04-15 09:25:03 -0600213 VkDebugReportCallbackEXT *callbacks) {
Ian Elliottad6300f2016-03-31 10:48:19 -0600214 free(infos);
215 free(callbacks);
216}
217
Jon Ashburncc407a22016-04-15 09:25:03 -0600218VkResult util_CreateDebugReportCallbacks(
219 struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
220 uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
221 VkDebugReportCallbackEXT *callbacks) {
Jamie Madill2b6b8d52016-04-04 15:09:51 -0400222 VkResult rtn = VK_SUCCESS;
Jon Ashburncc407a22016-04-15 09:25:03 -0600223 for (uint32_t i = 0; i < num_callbacks; i++) {
224 rtn = util_CreateDebugReportCallback(inst, &infos[i], pAllocator,
Ian Elliottad6300f2016-03-31 10:48:19 -0600225 callbacks[i]);
226 if (rtn != VK_SUCCESS) {
Jon Ashburncc407a22016-04-15 09:25:03 -0600227 for (uint32_t j = 0; j < i; j++) {
228 util_DestroyDebugReportCallback(inst, callbacks[j], pAllocator);
Ian Elliottad6300f2016-03-31 10:48:19 -0600229 }
230 return rtn;
231 }
232 }
233 return rtn;
234}
235
236void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
237 const VkAllocationCallbacks *pAllocator,
238 uint32_t num_callbacks,
Jon Ashburncc407a22016-04-15 09:25:03 -0600239 VkDebugReportCallbackEXT *callbacks) {
240 for (uint32_t i = 0; i < num_callbacks; i++) {
241 util_DestroyDebugReportCallback(inst, callbacks[i], pAllocator);
Ian Elliottad6300f2016-03-31 10:48:19 -0600242 }
243}
244
Jon Ashburn23d36b12016-02-02 17:47:28 -0700245static VKAPI_ATTR void VKAPI_CALL
246debug_report_DestroyDebugReportCallback(VkInstance instance,
247 VkDebugReportCallbackEXT callback,
248 VkAllocationCallbacks *pAllocator) {
Jon Ashburne0e64572015-09-30 12:56:42 -0600249 struct loader_instance *inst = loader_get_instance(instance);
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600250 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600251
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700252 inst->disp->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600253
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700254 util_DestroyDebugReportCallback(inst, callback, pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600255
Jon Ashburn6301a0f2015-05-29 13:15:39 -0600256 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600257}
258
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700259static VKAPI_ATTR void VKAPI_CALL debug_report_DebugReportMessage(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700260 VkInstance instance, VkDebugReportFlagsEXT flags,
261 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
262 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700263 struct loader_instance *inst = loader_get_instance(instance);
264
Jon Ashburn23d36b12016-02-02 17:47:28 -0700265 inst->disp->DebugReportMessageEXT(instance, flags, objType, object,
266 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700267}
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600268
269/*
270 * This is the instance chain terminator function
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700271 * for CreateDebugReportCallback
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600272 */
Tony Barbour1d2cd3f2015-07-03 10:33:54 -0600273
Jon Ashburn1530c342016-02-26 13:14:27 -0700274VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallback(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700275 VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
276 const VkAllocationCallbacks *pAllocator,
277 VkDebugReportCallbackEXT *pCallback) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700278 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600279 const struct loader_icd *icd;
Jon Ashburn23d36b12016-02-02 17:47:28 -0700280 struct loader_instance *inst = (struct loader_instance *)instance;
Karl Schultz2558bd32016-02-24 14:39:39 -0700281 VkResult res = VK_SUCCESS;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600282 uint32_t storage_idx;
283
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700284 icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600285 if (!icd_info) {
286 return VK_ERROR_OUT_OF_HOST_MEMORY;
287 }
288
289 storage_idx = 0;
290 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700291 if (!icd->CreateDebugReportCallbackEXT) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600292 continue;
293 }
294
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700295 res = icd->CreateDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700296 icd->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600297
298 if (res != VK_SUCCESS) {
299 break;
300 }
301 storage_idx++;
302 }
303
304 /* roll back on errors */
305 if (icd) {
306 storage_idx = 0;
307 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800308 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700309 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700310 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600311 }
312 storage_idx++;
313 }
314
315 return res;
316 }
317
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700318 *(VkDebugReportCallbackEXT **)pCallback = icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600319
320 return VK_SUCCESS;
321}
322
323/*
324 * This is the instance chain terminator function
Courtney Goeltzenleuchter05854bf2015-11-30 12:13:14 -0700325 * for DestroyDebugReportCallback
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600326 */
Jon Ashburn23d36b12016-02-02 17:47:28 -0700327VKAPI_ATTR void VKAPI_CALL
Jon Ashburn1530c342016-02-26 13:14:27 -0700328terminator_DestroyDebugReportCallback(VkInstance instance,
329 VkDebugReportCallbackEXT callback,
330 const VkAllocationCallbacks *pAllocator) {
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600331 uint32_t storage_idx;
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700332 VkDebugReportCallbackEXT *icd_info;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600333 const struct loader_icd *icd;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600334
Jon Ashburn23d36b12016-02-02 17:47:28 -0700335 struct loader_instance *inst = (struct loader_instance *)instance;
336 icd_info = *(VkDebugReportCallbackEXT **)&callback;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600337 storage_idx = 0;
338 for (icd = inst->icds; icd; icd = icd->next) {
Chia-I Wue2fc5522015-10-26 20:04:44 +0800339 if (icd_info[storage_idx]) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700340 icd->DestroyDebugReportCallbackEXT(
Jon Ashburn23d36b12016-02-02 17:47:28 -0700341 icd->instance, icd_info[storage_idx], pAllocator);
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600342 }
343 storage_idx++;
344 }
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600345}
346
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700347/*
348 * This is the instance chain terminator function
349 * for DebugReportMessage
350 */
Jon Ashburn23d36b12016-02-02 17:47:28 -0700351VKAPI_ATTR void VKAPI_CALL
Jon Ashburn1530c342016-02-26 13:14:27 -0700352terminator_DebugReportMessage(VkInstance instance, VkDebugReportFlagsEXT flags,
353 VkDebugReportObjectTypeEXT objType,
354 uint64_t object, size_t location, int32_t msgCode,
355 const char *pLayerPrefix, const char *pMsg) {
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700356 const struct loader_icd *icd;
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700357
Jon Ashburn23d36b12016-02-02 17:47:28 -0700358 struct loader_instance *inst = (struct loader_instance *)instance;
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700359
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700360 loader_platform_thread_lock_mutex(&loader_lock);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700361 for (icd = inst->icds; icd; icd = icd->next) {
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700362 if (icd->DebugReportMessageEXT != NULL) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700363 icd->DebugReportMessageEXT(icd->instance, flags, objType, object,
364 location, msgCode, pLayerPrefix, pMsg);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700365 }
366 }
367
368 /*
369 * Now that all ICDs have seen the message, call the necessary callbacks.
Jon Ashburn23d36b12016-02-02 17:47:28 -0700370 * Ignoring "bail" return value as there is nothing to bail from at this
371 * point.
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700372 */
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700373
Jon Ashburn23d36b12016-02-02 17:47:28 -0700374 util_DebugReportMessage(inst, flags, objType, object, location, msgCode,
375 pLayerPrefix, pMsg);
Courtney Goeltzenleuchter82887272015-12-02 15:29:33 -0700376
377 loader_platform_thread_unlock_mutex(&loader_lock);
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700378}
379
Jon Ashburn23d36b12016-02-02 17:47:28 -0700380bool debug_report_instance_gpa(struct loader_instance *ptr_instance,
381 const char *name, void **addr) {
Jon Ashburn8a39efc2015-11-06 11:02:40 -0700382 // debug_report is currently advertised to be supported by the loader,
383 // so always return the entry points if name matches and it's enabled
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600384 *addr = NULL;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600385
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700386 if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700387 *addr = ptr_instance->debug_report_enabled
388 ? (void *)debug_report_CreateDebugReportCallback
389 : NULL;
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600390 return true;
391 }
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700392 if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700393 *addr = ptr_instance->debug_report_enabled
394 ? (void *)debug_report_DestroyDebugReportCallback
395 : NULL;
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600396 return true;
397 }
Courtney Goeltzenleuchter7415d5a2015-12-09 15:48:16 -0700398 if (!strcmp("vkDebugReportMessageEXT", name)) {
Jon Ashburn23d36b12016-02-02 17:47:28 -0700399 *addr = ptr_instance->debug_report_enabled
400 ? (void *)debug_report_DebugReportMessage
401 : NULL;
Courtney Goeltzenleuchter822e8d72015-11-30 15:28:25 -0700402 return true;
403 }
Jon Ashburnf7a48db2015-10-01 12:03:17 -0600404 return false;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600405}