blob: 6d6c442eeacf322bf84818b865bdd96a72aa4f41 [file] [log] [blame]
Mark Younge3e9b562017-11-09 10:37:04 -07001/*
2 * Copyright (c) 2015-2017 The Khronos Group Inc.
3 * Copyright (c) 2015-2017 Valve Corporation
4 * Copyright (c) 2015-2017 LunarG, Inc.
5 * Copyright (C) 2015-2016 Google Inc.
6 *
7 * 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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * 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.
18 *
19 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
20 * Author: Jon Ashburn <jon@LunarG.com>
21 * Author: Mark Young <marky@lunarg.com>
22 *
23 */
24
Tom Andersona8358802018-07-25 17:10:16 -070025#ifndef _GNU_SOURCE
Mark Younge3e9b562017-11-09 10:37:04 -070026#define _GNU_SOURCE
Tom Andersona8358802018-07-25 17:10:16 -070027#endif
Mark Younge3e9b562017-11-09 10:37:04 -070028#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include <inttypes.h>
32#ifndef WIN32
33#include <signal.h>
34#else
35#endif
36#include "vk_loader_platform.h"
37#include "debug_utils.h"
38#include "vulkan/vk_layer.h"
39#include "vk_object_types.h"
40
41// VK_EXT_debug_report related items
42
43VkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
44 const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger) {
45 VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
46
47#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
48 {
49#else
50 if (pAllocator != NULL) {
51 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
52 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
53 } else {
54#endif
55 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
56 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
57 }
58 if (!pNewDbgFuncNode) {
59 return VK_ERROR_OUT_OF_HOST_MEMORY;
60 }
61 memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
62
63 pNewDbgFuncNode->is_messenger = true;
64 pNewDbgFuncNode->messenger.messenger = messenger;
65 pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
66 pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
67 pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
68 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
69 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
70 inst->DbgFunctionHead = pNewDbgFuncNode;
71
72 return VK_SUCCESS;
73}
74
75static VKAPI_ATTR VkResult VKAPI_CALL
76debug_utils_CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
77 const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pMessenger) {
78 struct loader_instance *inst = loader_get_instance(instance);
79 loader_platform_thread_lock_mutex(&loader_lock);
80 VkResult result = inst->disp->layer_inst_disp.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
81 loader_platform_thread_unlock_mutex(&loader_lock);
82 return result;
83}
84
85VkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
86 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
87 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
88 VkBool32 bail = false;
89
90 if (NULL != pCallbackData && NULL != pCallbackData->pObjects && 0 < pCallbackData->objectCount) {
91 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
92 VkDebugReportObjectTypeEXT object_type;
93 VkDebugReportFlagsEXT object_flags = 0;
94 uint64_t object_handle;
95
96 debug_utils_AnnotFlagsToReportFlags(messageSeverity, messageTypes, &object_flags);
97 debug_utils_AnnotObjectToDebugReportObject(pCallbackData->pObjects, &object_type, &object_handle);
98
99 while (pTrav) {
100 if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & messageSeverity) &&
101 (pTrav->messenger.messageType & messageTypes)) {
102 if (pTrav->messenger.pfnUserCallback(messageSeverity, messageTypes, pCallbackData, pTrav->pUserData)) {
103 bail = true;
104 }
105 }
106 if (!pTrav->is_messenger && pTrav->report.msgFlags & object_flags) {
107 if (pTrav->report.pfnMsgCallback(object_flags, object_type, object_handle, 0, pCallbackData->messageIdNumber,
108 pCallbackData->pMessageIdName, pCallbackData->pMessage, pTrav->pUserData)) {
109 bail = true;
110 }
111 }
112
113 pTrav = pTrav->pNext;
114 }
115 }
116
117 return bail;
118}
119
120void util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
121 const VkAllocationCallbacks *pAllocator) {
122 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
123 VkLayerDbgFunctionNode *pPrev = pTrav;
124
125 while (pTrav) {
126 if (pTrav->is_messenger && pTrav->messenger.messenger == messenger) {
127 pPrev->pNext = pTrav->pNext;
128 if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
129#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
130 {
131#else
132 if (pAllocator != NULL) {
133 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
134 } else {
135#endif
136 loader_instance_heap_free(inst, pTrav);
137 }
138 break;
139 }
140 pPrev = pTrav;
141 pTrav = pTrav->pNext;
142 }
143}
144
145// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
146// counts any VkDebugUtilsMessengerCreateInfoEXT structs that it finds. It
147// then allocates array that can hold that many structs, as well as that many
148// VkDebugUtilsMessengerEXT handles. It then copies each
149// VkDebugUtilsMessengerCreateInfoEXT, and initializes each handle.
150VkResult util_CopyDebugUtilsMessengerCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator,
151 uint32_t *num_messengers, VkDebugUtilsMessengerCreateInfoEXT **infos,
152 VkDebugUtilsMessengerEXT **messengers) {
153 uint32_t n = *num_messengers = 0;
154 VkDebugUtilsMessengerCreateInfoEXT *pInfos = NULL;
155 VkDebugUtilsMessengerEXT *pMessengers = NULL;
156
157 const void *pNext = pChain;
158 while (pNext) {
159 // 1st, count the number VkDebugUtilsMessengerCreateInfoEXT:
160 if (((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
161 n++;
162 }
163 pNext = (void *)((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->pNext;
164 }
165 if (n == 0) {
166 return VK_SUCCESS;
167 }
168
169// 2nd, allocate memory for each VkDebugUtilsMessengerCreateInfoEXT:
170#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
171 {
172#else
173 if (pAllocator != NULL) {
174 pInfos = *infos = ((VkDebugUtilsMessengerCreateInfoEXT *)pAllocator->pfnAllocation(
175 pAllocator->pUserData, n * sizeof(VkDebugUtilsMessengerCreateInfoEXT), sizeof(void *),
176 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
177 } else {
178#endif
179 pInfos = *infos = ((VkDebugUtilsMessengerCreateInfoEXT *)malloc(n * sizeof(VkDebugUtilsMessengerCreateInfoEXT)));
180 }
181 if (!pInfos) {
182 return VK_ERROR_OUT_OF_HOST_MEMORY;
183 }
184// 3rd, allocate memory for a unique handle for each callback:
185#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
186 {
187#else
188 if (pAllocator != NULL) {
189 pMessengers = *messengers = ((VkDebugUtilsMessengerEXT *)pAllocator->pfnAllocation(
190 pAllocator->pUserData, n * sizeof(VkDebugUtilsMessengerEXT), sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
191 if (NULL == pMessengers) {
192 pAllocator->pfnFree(pAllocator->pUserData, pInfos);
193 return VK_ERROR_OUT_OF_HOST_MEMORY;
194 }
195 } else {
196#endif
197 pMessengers = *messengers = ((VkDebugUtilsMessengerEXT *)malloc(n * sizeof(VkDebugUtilsMessengerEXT)));
198 if (NULL == pMessengers) {
199 free(pInfos);
200 return VK_ERROR_OUT_OF_HOST_MEMORY;
201 }
202 }
203 // 4th, copy each VkDebugUtilsMessengerCreateInfoEXT for use by
204 // vkDestroyInstance, and assign a unique handle to each messenger (just
205 // use the address of the copied VkDebugUtilsMessengerCreateInfoEXT):
206 pNext = pChain;
207 while (pNext) {
208 if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
209 memcpy(pInfos, pNext, sizeof(VkDebugUtilsMessengerCreateInfoEXT));
210 *pMessengers++ = (VkDebugUtilsMessengerEXT)(uintptr_t)pInfos++;
211 }
212 pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
213 }
214
215 *num_messengers = n;
216 return VK_SUCCESS;
217}
218
219void util_FreeDebugUtilsMessengerCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerCreateInfoEXT *infos,
220 VkDebugUtilsMessengerEXT *messengers) {
221#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
222 {
223#else
224 if (pAllocator != NULL) {
225 pAllocator->pfnFree(pAllocator->pUserData, infos);
226 pAllocator->pfnFree(pAllocator->pUserData, messengers);
227 } else {
228#endif
229 free(infos);
230 free(messengers);
231 }
232}
233
234VkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
235 uint32_t num_messengers, VkDebugUtilsMessengerCreateInfoEXT *infos,
236 VkDebugUtilsMessengerEXT *messengers) {
237 VkResult rtn = VK_SUCCESS;
238 for (uint32_t i = 0; i < num_messengers; i++) {
239 rtn = util_CreateDebugUtilsMessenger(inst, &infos[i], pAllocator, messengers[i]);
240 if (rtn != VK_SUCCESS) {
241 for (uint32_t j = 0; j < i; j++) {
242 util_DestroyDebugUtilsMessenger(inst, messengers[j], pAllocator);
243 }
244 return rtn;
245 }
246 }
247 return rtn;
248}
249
250void util_DestroyDebugUtilsMessengers(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
251 uint32_t num_messengers, VkDebugUtilsMessengerEXT *messengers) {
252 for (uint32_t i = 0; i < num_messengers; i++) {
253 util_DestroyDebugUtilsMessenger(inst, messengers[i], pAllocator);
254 }
255}
256
257static VKAPI_ATTR void VKAPI_CALL debug_utils_SubmitDebugUtilsMessageEXT(
258 VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
259 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
260 struct loader_instance *inst = loader_get_instance(instance);
261
262 inst->disp->layer_inst_disp.SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
263}
264
265static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
266 const VkAllocationCallbacks *pAllocator) {
267 struct loader_instance *inst = loader_get_instance(instance);
268 loader_platform_thread_lock_mutex(&loader_lock);
269
270 inst->disp->layer_inst_disp.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
271
272 util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
273
274 loader_platform_thread_unlock_mutex(&loader_lock);
275}
276
277// This is the instance chain terminator function for CreateDebugUtilsMessenger
278VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstance instance,
279 const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
280 const VkAllocationCallbacks *pAllocator,
281 VkDebugUtilsMessengerEXT *pMessenger) {
282 VkDebugUtilsMessengerEXT *icd_info = NULL;
283 const struct loader_icd_term *icd_term;
284 struct loader_instance *inst = (struct loader_instance *)instance;
285 VkResult res = VK_SUCCESS;
286 uint32_t storage_idx;
287 VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
288
289#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
290 {
291#else
292 if (pAllocator != NULL) {
293 icd_info = ((VkDebugUtilsMessengerEXT *)pAllocator->pfnAllocation(pAllocator->pUserData,
294 inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT),
295 sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
296 if (icd_info) {
297 memset(icd_info, 0, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT));
298 }
299 } else {
300#endif
301 icd_info = calloc(sizeof(VkDebugUtilsMessengerEXT), inst->total_icd_count);
302 }
303 if (!icd_info) {
304 res = VK_ERROR_OUT_OF_HOST_MEMORY;
305 goto out;
306 }
307
308 storage_idx = 0;
309 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
310 if (!icd_term->dispatch.CreateDebugUtilsMessengerEXT) {
311 continue;
312 }
313
314 res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
315
316 if (res != VK_SUCCESS) {
317 goto out;
318 }
319 storage_idx++;
320 }
321
322// Setup the debug report callback in the terminator since a layer may want
323// to grab the information itself (RenderDoc) and then return back to the
324// user callback a sub-set of the messages.
325#if (DEBUG_DISABLE_APP_ALLOCATORS == 0)
326 if (pAllocator != NULL) {
327 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
328 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
329 } else {
330#else
331 {
332#endif
333 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
334 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
335 }
336 if (!pNewDbgFuncNode) {
337 res = VK_ERROR_OUT_OF_HOST_MEMORY;
338 goto out;
339 }
340 memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
341
342 pNewDbgFuncNode->is_messenger = true;
343 pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
344 pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
345 pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
346 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
347 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
348 inst->DbgFunctionHead = pNewDbgFuncNode;
349
350 *(VkDebugUtilsMessengerEXT **)pMessenger = icd_info;
351 pNewDbgFuncNode->messenger.messenger = *pMessenger;
352
353out:
354
355 // Roll back on errors
356 if (VK_SUCCESS != res) {
357 storage_idx = 0;
358 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
359 if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
360 continue;
361 }
362
363 if (icd_info && icd_info[storage_idx]) {
364 icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
365 }
366 storage_idx++;
367 }
368
369#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
370 {
371#else
372 if (pAllocator != NULL) {
373 if (NULL != pNewDbgFuncNode) {
374 pAllocator->pfnFree(pAllocator->pUserData, pNewDbgFuncNode);
375 }
376 if (NULL != icd_info) {
377 pAllocator->pfnFree(pAllocator->pUserData, icd_info);
378 }
379 } else {
380#endif
381 if (NULL != pNewDbgFuncNode) {
382 free(pNewDbgFuncNode);
383 }
384 if (NULL != icd_info) {
385 free(icd_info);
386 }
387 }
388 }
389
390 return res;
391}
392
393// This is the instance chain terminator function for DestroyDebugUtilsMessenger
394VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
395 const VkAllocationCallbacks *pAllocator) {
396 uint32_t storage_idx;
397 VkDebugUtilsMessengerEXT *icd_info;
398 const struct loader_icd_term *icd_term;
399
400 struct loader_instance *inst = (struct loader_instance *)instance;
401 icd_info = *(VkDebugUtilsMessengerEXT **)&messenger;
402 storage_idx = 0;
403 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
404 if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
405 continue;
406 }
407
408 if (icd_info[storage_idx]) {
409 icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
410 }
411 storage_idx++;
412 }
413
414#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
415 {
416#else
417 if (pAllocator != NULL) {
418 pAllocator->pfnFree(pAllocator->pUserData, icd_info);
419 } else {
420#endif
421 free(icd_info);
422 }
423}
424
425// This is the instance chain terminator function for SubmitDebugUtilsMessageEXT
426VKAPI_ATTR void VKAPI_CALL terminator_SubmitDebugUtilsMessageEXT(VkInstance instance,
427 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
428 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
429 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
430 const struct loader_icd_term *icd_term;
431
432 struct loader_instance *inst = (struct loader_instance *)instance;
433
434 loader_platform_thread_lock_mutex(&loader_lock);
435 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
436 if (icd_term->dispatch.SubmitDebugUtilsMessageEXT != NULL) {
437 icd_term->dispatch.SubmitDebugUtilsMessageEXT(icd_term->instance, messageSeverity, messageTypes, pCallbackData);
438 }
439 }
440
441 // Now that all ICDs have seen the message, call the necessary callbacks. Ignoring "bail" return value
442 // as there is nothing to bail from at this point.
443
444 util_SubmitDebugUtilsMessageEXT(inst, messageSeverity, messageTypes, pCallbackData);
445
446 loader_platform_thread_unlock_mutex(&loader_lock);
447}
448
449// VK_EXT_debug_report related items
450
451VkResult util_CreateDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
452 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback) {
453 VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
454
455#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
456 {
457#else
458 if (pAllocator != NULL) {
459 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
460 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
461 } else {
462#endif
463 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
464 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
465 }
466 if (!pNewDbgFuncNode) {
467 return VK_ERROR_OUT_OF_HOST_MEMORY;
468 }
469 memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
470
471 pNewDbgFuncNode->is_messenger = false;
472 pNewDbgFuncNode->report.msgCallback = callback;
473 pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
474 pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
475 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
476 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
477 inst->DbgFunctionHead = pNewDbgFuncNode;
478
479 return VK_SUCCESS;
480}
481
482static VKAPI_ATTR VkResult VKAPI_CALL
483debug_utils_CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
484 const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
485 struct loader_instance *inst = loader_get_instance(instance);
486 loader_platform_thread_lock_mutex(&loader_lock);
487 VkResult result = inst->disp->layer_inst_disp.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
488 loader_platform_thread_unlock_mutex(&loader_lock);
489 return result;
490}
491
492// Utility function to handle reporting
493VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
494 uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
495 VkBool32 bail = false;
496 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
497 VkDebugUtilsMessageSeverityFlagBitsEXT severity;
498 VkDebugUtilsMessageTypeFlagsEXT types;
499 VkDebugUtilsMessengerCallbackDataEXT callback_data;
500 VkDebugUtilsObjectNameInfoEXT object_name;
501
502 debug_utils_ReportFlagsToAnnotFlags(msgFlags, false, &severity, &types);
503 debug_utils_ReportObjectToAnnotObject(objectType, srcObject, &object_name);
504
505 callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
506 callback_data.pNext = NULL;
507 callback_data.flags = 0;
508 callback_data.pMessageIdName = pLayerPrefix;
509 callback_data.messageIdNumber = msgCode;
510 callback_data.pMessage = pMsg;
511 callback_data.cmdBufLabelCount = 0;
512 callback_data.pCmdBufLabels = NULL;
513 callback_data.queueLabelCount = 0;
514 callback_data.pQueueLabels = NULL;
515 callback_data.objectCount = 1;
516 callback_data.pObjects = &object_name;
517
518 while (pTrav) {
519 if (!pTrav->is_messenger && pTrav->report.msgFlags & msgFlags) {
520 if (pTrav->report.pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, pMsg,
521 pTrav->pUserData)) {
522 bail = true;
523 }
524 }
525 if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & severity) && (pTrav->messenger.messageType & types)) {
526 if (pTrav->messenger.pfnUserCallback(severity, types, &callback_data, pTrav->pUserData)) {
527 bail = true;
528 }
529 }
530
531 pTrav = pTrav->pNext;
532 }
533
534 return bail;
535}
536
537void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
538 const VkAllocationCallbacks *pAllocator) {
539 VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
540 VkLayerDbgFunctionNode *pPrev = pTrav;
541
542 while (pTrav) {
543 if (!pTrav->is_messenger && pTrav->report.msgCallback == callback) {
544 pPrev->pNext = pTrav->pNext;
545 if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
546#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
547 {
548#else
549 if (pAllocator != NULL) {
550 pAllocator->pfnFree(pAllocator->pUserData, pTrav);
551 } else {
552#endif
553 loader_instance_heap_free(inst, pTrav);
554 }
555 break;
556 }
557 pPrev = pTrav;
558 pTrav = pTrav->pNext;
559 }
560}
561
562// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
563// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
564// then allocates array that can hold that many structs, as well as that many
565// VkDebugReportCallbackEXT handles. It then copies each
566// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
567VkResult util_CopyDebugReportCreateInfos(const void *pChain, const VkAllocationCallbacks *pAllocator, uint32_t *num_callbacks,
568 VkDebugReportCallbackCreateInfoEXT **infos, VkDebugReportCallbackEXT **callbacks) {
569 uint32_t n = *num_callbacks = 0;
570 VkDebugReportCallbackCreateInfoEXT *pInfos = NULL;
571 VkDebugReportCallbackEXT *pCallbacks = NULL;
572
573 const void *pNext = pChain;
574 while (pNext) {
575 // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
576 if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
577 n++;
578 }
579 pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
580 }
581 if (n == 0) {
582 return VK_SUCCESS;
583 }
584
585// 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
586#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
587 {
588#else
589 if (pAllocator != NULL) {
590 pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)pAllocator->pfnAllocation(
591 pAllocator->pUserData, n * sizeof(VkDebugReportCallbackCreateInfoEXT), sizeof(void *),
592 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
593 } else {
594#endif
595 pInfos = *infos = ((VkDebugReportCallbackCreateInfoEXT *)malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
596 }
597 if (!pInfos) {
598 return VK_ERROR_OUT_OF_HOST_MEMORY;
599 }
600// 3rd, allocate memory for a unique handle for each callback:
601#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
602 {
603#else
604 if (pAllocator != NULL) {
605 pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(
606 pAllocator->pUserData, n * sizeof(VkDebugReportCallbackEXT), sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
607 if (!pCallbacks) {
608 pAllocator->pfnFree(pAllocator->pUserData, pInfos);
609 return VK_ERROR_OUT_OF_HOST_MEMORY;
610 }
611 } else {
612#endif
613 pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(n * sizeof(VkDebugReportCallbackEXT)));
614 if (!pCallbacks) {
615 free(pInfos);
616 return VK_ERROR_OUT_OF_HOST_MEMORY;
617 }
618 }
619 // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
620 // vkDestroyInstance, and assign a unique handle to each callback (just
621 // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
622 pNext = pChain;
623 while (pNext) {
624 if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
625 memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
626 *pCallbacks++ = (VkDebugReportCallbackEXT)(uintptr_t)pInfos++;
627 }
628 pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
629 }
630
631 *num_callbacks = n;
632 return VK_SUCCESS;
633}
634
635void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackCreateInfoEXT *infos,
636 VkDebugReportCallbackEXT *callbacks) {
637#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
638 {
639#else
640 if (pAllocator != NULL) {
641 pAllocator->pfnFree(pAllocator->pUserData, infos);
642 pAllocator->pfnFree(pAllocator->pUserData, callbacks);
643 } else {
644#endif
645 free(infos);
646 free(callbacks);
647 }
648}
649
650VkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator,
651 uint32_t num_callbacks, VkDebugReportCallbackCreateInfoEXT *infos,
652 VkDebugReportCallbackEXT *callbacks) {
653 VkResult rtn = VK_SUCCESS;
654 for (uint32_t i = 0; i < num_callbacks; i++) {
655 rtn = util_CreateDebugReportCallback(inst, &infos[i], pAllocator, callbacks[i]);
656 if (rtn != VK_SUCCESS) {
657 for (uint32_t j = 0; j < i; j++) {
658 util_DestroyDebugReportCallback(inst, callbacks[j], pAllocator);
659 }
660 return rtn;
661 }
662 }
663 return rtn;
664}
665
666void util_DestroyDebugReportCallbacks(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator, uint32_t num_callbacks,
667 VkDebugReportCallbackEXT *callbacks) {
668 for (uint32_t i = 0; i < num_callbacks; i++) {
669 util_DestroyDebugReportCallback(inst, callbacks[i], pAllocator);
670 }
671}
672
673static VKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
674 const VkAllocationCallbacks *pAllocator) {
675 struct loader_instance *inst = loader_get_instance(instance);
676 loader_platform_thread_lock_mutex(&loader_lock);
677
678 inst->disp->layer_inst_disp.DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
679
680 util_DestroyDebugReportCallback(inst, callback, pAllocator);
681
682 loader_platform_thread_unlock_mutex(&loader_lock);
683}
684
685static VKAPI_ATTR void VKAPI_CALL debug_utils_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
686 VkDebugReportObjectTypeEXT objType, uint64_t object,
687 size_t location, int32_t msgCode, const char *pLayerPrefix,
688 const char *pMsg) {
689 struct loader_instance *inst = loader_get_instance(instance);
690
691 inst->disp->layer_inst_disp.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
692}
693
694// This is the instance chain terminator function
695// for CreateDebugReportCallback
696VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstance instance,
697 const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
698 const VkAllocationCallbacks *pAllocator,
699 VkDebugReportCallbackEXT *pCallback) {
700 VkDebugReportCallbackEXT *icd_info = NULL;
701 const struct loader_icd_term *icd_term;
702 struct loader_instance *inst = (struct loader_instance *)instance;
703 VkResult res = VK_SUCCESS;
704 uint32_t storage_idx;
705 VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
706
707#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
708 {
709#else
710 if (pAllocator != NULL) {
711 icd_info = ((VkDebugReportCallbackEXT *)pAllocator->pfnAllocation(pAllocator->pUserData,
712 inst->total_icd_count * sizeof(VkDebugReportCallbackEXT),
713 sizeof(void *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
714 if (icd_info) {
715 memset(icd_info, 0, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT));
716 }
717 } else {
718#endif
719 icd_info = calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
720 }
721 if (!icd_info) {
722 res = VK_ERROR_OUT_OF_HOST_MEMORY;
723 goto out;
724 }
725
726 storage_idx = 0;
727 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
728 if (!icd_term->dispatch.CreateDebugReportCallbackEXT) {
729 continue;
730 }
731
732 res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
733
734 if (res != VK_SUCCESS) {
735 goto out;
736 }
737 storage_idx++;
738 }
739
740// Setup the debug report callback in the terminator since a layer may want
741// to grab the information itself (RenderDoc) and then return back to the
742// user callback a sub-set of the messages.
743#if (DEBUG_DISABLE_APP_ALLOCATORS == 0)
744 if (pAllocator != NULL) {
745 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)pAllocator->pfnAllocation(pAllocator->pUserData, sizeof(VkLayerDbgFunctionNode),
746 sizeof(int *), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
747 } else {
748#else
749 {
750#endif
751 pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_instance_heap_alloc(inst, sizeof(VkLayerDbgFunctionNode),
752 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
753 }
754 if (!pNewDbgFuncNode) {
755 res = VK_ERROR_OUT_OF_HOST_MEMORY;
756 goto out;
757 }
758 memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
759
760 pNewDbgFuncNode->is_messenger = false;
761 pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
762 pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
763 pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
764 pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
765 inst->DbgFunctionHead = pNewDbgFuncNode;
766
767 *(VkDebugReportCallbackEXT **)pCallback = icd_info;
768 pNewDbgFuncNode->report.msgCallback = *pCallback;
769
770out:
771
772 // Roll back on errors
773 if (VK_SUCCESS != res) {
774 storage_idx = 0;
775 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
776 if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
777 continue;
778 }
779
780 if (icd_info && icd_info[storage_idx]) {
781 icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
782 }
783 storage_idx++;
784 }
785
786#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
787 {
788#else
789 if (pAllocator != NULL) {
790 if (NULL != pNewDbgFuncNode) {
791 pAllocator->pfnFree(pAllocator->pUserData, pNewDbgFuncNode);
792 }
793 if (NULL != icd_info) {
794 pAllocator->pfnFree(pAllocator->pUserData, icd_info);
795 }
796 } else {
797#endif
798 if (NULL != pNewDbgFuncNode) {
799 free(pNewDbgFuncNode);
800 }
801 if (NULL != icd_info) {
802 free(icd_info);
803 }
804 }
805 }
806
807 return res;
808}
809
810// This is the instance chain terminator function for DestroyDebugReportCallback
811VKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
812 const VkAllocationCallbacks *pAllocator) {
813 uint32_t storage_idx;
814 VkDebugReportCallbackEXT *icd_info;
815 const struct loader_icd_term *icd_term;
816
817 struct loader_instance *inst = (struct loader_instance *)instance;
818 icd_info = *(VkDebugReportCallbackEXT **)&callback;
819 storage_idx = 0;
820 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
821 if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
822 continue;
823 }
824
825 if (icd_info[storage_idx]) {
826 icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
827 }
828 storage_idx++;
829 }
830
831#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
832 {
833#else
834 if (pAllocator != NULL) {
835 pAllocator->pfnFree(pAllocator->pUserData, icd_info);
836 } else {
837#endif
838 free(icd_info);
839 }
840}
841
842// This is the instance chain terminator function for DebugReportMessage
843VKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
844 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
845 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
846 const struct loader_icd_term *icd_term;
847
848 struct loader_instance *inst = (struct loader_instance *)instance;
849
850 loader_platform_thread_lock_mutex(&loader_lock);
851 for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
852 if (icd_term->dispatch.DebugReportMessageEXT != NULL) {
853 icd_term->dispatch.DebugReportMessageEXT(icd_term->instance, flags, objType, object, location, msgCode, pLayerPrefix,
854 pMsg);
855 }
856 }
857
858 // Now that all ICDs have seen the message, call the necessary callbacks. Ignoring "bail" return value
859 // as there is nothing to bail from at this point.
860
861 util_DebugReportMessage(inst, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
862
863 loader_platform_thread_unlock_mutex(&loader_lock);
864}
865
866// General utilities
867
868static const VkExtensionProperties debug_utils_extension_info[] = {
869 {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
870 {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
871};
872
873void debug_utils_AddInstanceExtensions(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
874 loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
875 debug_utils_extension_info);
876}
877
878void debug_utils_CreateInstance(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
879 ptr_instance->enabled_known_extensions.ext_debug_report = 0;
880 ptr_instance->enabled_known_extensions.ext_debug_utils = 0;
881
882 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
883 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
884 ptr_instance->enabled_known_extensions.ext_debug_report = 1;
885 } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
886 ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
887 }
888 }
889}
890
891bool debug_utils_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
892 bool ret_type = false;
893
894 *addr = NULL;
895
Lenny Komow1de11122018-02-22 11:54:18 -0700896 if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
897 *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_CreateDebugReportCallbackEXT : NULL;
898 ret_type = true;
899 } else if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
900 *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DestroyDebugReportCallbackEXT : NULL;
901 ret_type = true;
902 } else if (!strcmp("vkDebugReportMessageEXT", name)) {
903 *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DebugReportMessageEXT : NULL;
904 return true;
Mark Younge3e9b562017-11-09 10:37:04 -0700905 }
Lenny Komow1de11122018-02-22 11:54:18 -0700906 if (!strcmp("vkCreateDebugUtilsMessengerEXT", name)) {
907 *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_CreateDebugUtilsMessengerEXT : NULL;
908 ret_type = true;
909 } else if (!strcmp("vkDestroyDebugUtilsMessengerEXT", name)) {
910 *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_DestroyDebugUtilsMessengerEXT : NULL;
911 ret_type = true;
912 } else if (!strcmp("vkSubmitDebugUtilsMessageEXT", name)) {
913 *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_SubmitDebugUtilsMessageEXT : NULL;
914 ret_type = true;
Mark Younge3e9b562017-11-09 10:37:04 -0700915 }
916
917 return ret_type;
918}
919
920bool debug_utils_ReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
921 VkDebugUtilsMessageSeverityFlagBitsEXT *da_severity,
922 VkDebugUtilsMessageTypeFlagsEXT *da_type) {
923 bool type_set = false;
924 if (NULL == da_severity || NULL == da_type) {
925 return false;
926 }
927 *da_type = 0;
John Zulaufa95b00f2018-04-12 13:15:47 -0600928 *da_severity = 0;
Mark Younge3e9b562017-11-09 10:37:04 -0700929
930 if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
931 *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
932 *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
933 type_set = true;
934 } else if ((dr_flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) != 0) {
935 *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
936 } else if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
937 *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
938 } else if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
939 *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
940 *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
941 type_set = true;
942 }
943
944 if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
945 *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
946 } else if (!type_set) {
947 if (default_flag_is_spec) {
948 *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
949 } else {
950 *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
951 }
952 }
953
954 return true;
955}
956
957bool debug_utils_AnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
958 VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags) {
959 if (NULL == dr_flags) {
960 return false;
961 }
962
963 *dr_flags = 0;
964
965 if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
966 *dr_flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
967 } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) {
968 if ((da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0) {
969 *dr_flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
970 } else {
971 *dr_flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
972 }
973 } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
974 *dr_flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
975 } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
976 *dr_flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
977 }
978
979 return true;
980}
981
982bool debug_utils_ReportObjectToAnnotObject(VkDebugReportObjectTypeEXT dr_object_type, uint64_t object_handle,
983 VkDebugUtilsObjectNameInfoEXT *da_object_name_info) {
984 if (NULL == da_object_name_info) {
985 return false;
986 }
987 da_object_name_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
988 da_object_name_info->pNext = NULL;
989 da_object_name_info->objectHandle = (uint64_t)(uintptr_t)object_handle;
990 da_object_name_info->pObjectName = NULL;
991 da_object_name_info->objectType = convertDebugReportObjectToCoreObject(dr_object_type);
992 return true;
993}
994
995bool debug_utils_AnnotObjectToDebugReportObject(const VkDebugUtilsObjectNameInfoEXT *da_object_name_info,
996 VkDebugReportObjectTypeEXT *dr_object_type, uint64_t *dr_object_handle) {
997 if (NULL == da_object_name_info || NULL == dr_object_type || NULL == dr_object_handle) {
998 return false;
999 }
1000 *dr_object_type = convertCoreObjectToDebugReportObject(da_object_name_info->objectType);
1001 *dr_object_handle = da_object_name_info->objectHandle;
1002 return true;
1003}