1 /* 2 * Copyright 2017 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #include "vk_debug_report.h" 25 26 #include "vk_alloc.h" 27 #include "vk_util.h" 28 29 VkResult vk_debug_report_instance_init(struct vk_debug_report_instance *instance) 30 { 31 if (pthread_mutex_init(&instance->callbacks_mutex, NULL) != 0) { 32 return VK_ERROR_INITIALIZATION_FAILED; 33 } 34 35 list_inithead(&instance->callbacks); 36 37 return VK_SUCCESS; 38 } 39 40 void vk_debug_report_instance_destroy(struct vk_debug_report_instance *instance) 41 { 42 pthread_mutex_destroy(&instance->callbacks_mutex); 43 } 44 45 VkResult 46 vk_create_debug_report_callback(struct vk_debug_report_instance *instance, 47 const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, 48 const VkAllocationCallbacks* pAllocator, 49 const VkAllocationCallbacks* instance_allocator, 50 VkDebugReportCallbackEXT* pCallback) 51 { 52 53 struct vk_debug_report_callback *cb = 54 vk_alloc2(instance_allocator, pAllocator, 55 sizeof(struct vk_debug_report_callback), 8, 56 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 57 58 if (!cb) 59 return VK_ERROR_OUT_OF_HOST_MEMORY; 60 61 cb->flags = pCreateInfo->flags; 62 cb->callback = pCreateInfo->pfnCallback; 63 cb->data = pCreateInfo->pUserData; 64 65 pthread_mutex_lock(&instance->callbacks_mutex); 66 list_addtail(&cb->link, &instance->callbacks); 67 pthread_mutex_unlock(&instance->callbacks_mutex); 68 69 *pCallback = (VkDebugReportCallbackEXT)(uintptr_t)cb; 70 71 return VK_SUCCESS; 72 } 73 74 void 75 vk_destroy_debug_report_callback(struct vk_debug_report_instance *instance, 76 VkDebugReportCallbackEXT _callback, 77 const VkAllocationCallbacks* pAllocator, 78 const VkAllocationCallbacks* instance_allocator) 79 { 80 struct vk_debug_report_callback *callback = 81 (struct vk_debug_report_callback *)(uintptr_t)_callback; 82 83 /* Remove from list and destroy given callback. */ 84 pthread_mutex_lock(&instance->callbacks_mutex); 85 list_del(&callback->link); 86 vk_free2(instance_allocator, pAllocator, callback); 87 pthread_mutex_unlock(&instance->callbacks_mutex); 88 } 89 90 91 void 92 vk_debug_report(struct vk_debug_report_instance *instance, 93 VkDebugReportFlagsEXT flags, 94 VkDebugReportObjectTypeEXT object_type, 95 uint64_t handle, 96 size_t location, 97 int32_t messageCode, 98 const char* pLayerPrefix, 99 const char *pMessage) 100 { 101 /* Allow NULL for convinience, return if no callbacks registered. */ 102 if (!instance || list_empty(&instance->callbacks)) 103 return; 104 105 pthread_mutex_lock(&instance->callbacks_mutex); 106 107 /* Section 33.2 of the Vulkan 1.0.59 spec says: 108 * 109 * "callback is an externally synchronized object and must not be 110 * used on more than one thread at a time. This means that 111 * vkDestroyDebugReportCallbackEXT must not be called when a callback 112 * is active." 113 */ 114 list_for_each_entry(struct vk_debug_report_callback, cb, 115 &instance->callbacks, link) { 116 if (cb->flags & flags) 117 cb->callback(flags, object_type, handle, location, messageCode, 118 pLayerPrefix, pMessage, cb->data); 119 } 120 121 pthread_mutex_unlock(&instance->callbacks_mutex); 122 } 123