debug_report.cpp revision 6fecdd563f3bf94dadedc78512a1b28c08c67e07
1/* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "loader.h" 18 19namespace vulkan { 20 21VkResult DebugReportCallbackList::CreateCallback( 22 VkInstance instance, 23 const VkDebugReportCallbackCreateInfoEXT* create_info, 24 const VkAllocationCallbacks* allocator, 25 VkDebugReportCallbackEXT* callback) { 26 VkDebugReportCallbackEXT driver_callback = VK_NULL_HANDLE; 27 28 if (GetDriverDispatch(instance).CreateDebugReportCallbackEXT) { 29 VkResult result = 30 GetDriverDispatch(instance).CreateDebugReportCallbackEXT( 31 GetDriverInstance(instance), create_info, allocator, 32 &driver_callback); 33 if (result != VK_SUCCESS) 34 return result; 35 } 36 37 const VkAllocationCallbacks* alloc = 38 allocator ? allocator : GetAllocator(instance); 39 void* mem = 40 alloc->pfnAllocation(alloc->pUserData, sizeof(Node), alignof(Node), 41 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 42 if (!mem) { 43 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { 44 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( 45 GetDriverInstance(instance), driver_callback, allocator); 46 } 47 return VK_ERROR_OUT_OF_HOST_MEMORY; 48 } 49 50 std::lock_guard<decltype(rwmutex_)> lock(rwmutex_); 51 head_.next = 52 new (mem) Node{head_.next, create_info->flags, create_info->pfnCallback, 53 create_info->pUserData, driver_callback}; 54 *callback = 55 VkDebugReportCallbackEXT(reinterpret_cast<uintptr_t>(head_.next)); 56 return VK_SUCCESS; 57} 58 59void DebugReportCallbackList::DestroyCallback( 60 VkInstance instance, 61 VkDebugReportCallbackEXT callback, 62 const VkAllocationCallbacks* allocator) { 63 Node* node = reinterpret_cast<Node*>(uintptr_t(callback)); 64 std::unique_lock<decltype(rwmutex_)> lock(rwmutex_); 65 Node* prev = &head_; 66 while (prev && prev->next != node) 67 prev = prev->next; 68 prev->next = node->next; 69 lock.unlock(); 70 71 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { 72 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( 73 GetDriverInstance(instance), node->driver_callback, allocator); 74 } 75 76 const VkAllocationCallbacks* alloc = 77 allocator ? allocator : GetAllocator(instance); 78 alloc->pfnFree(alloc->pUserData, node); 79} 80 81void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, 82 VkDebugReportObjectTypeEXT object_type, 83 uint64_t object, 84 size_t location, 85 int32_t message_code, 86 const char* layer_prefix, 87 const char* message) { 88 std::shared_lock<decltype(rwmutex_)> lock(rwmutex_); 89 Node* node = &head_; 90 while ((node = node->next)) { 91 if ((node->flags & flags) != 0) { 92 node->callback(flags, object_type, object, location, message_code, 93 layer_prefix, message, node->data); 94 } 95 } 96} 97 98VkResult CreateDebugReportCallbackEXT_Bottom( 99 VkInstance instance, 100 const VkDebugReportCallbackCreateInfoEXT* create_info, 101 const VkAllocationCallbacks* allocator, 102 VkDebugReportCallbackEXT* callback) { 103 return GetDebugReportCallbacks(instance).CreateCallback( 104 instance, create_info, allocator, callback); 105} 106 107void DestroyDebugReportCallbackEXT_Bottom( 108 VkInstance instance, 109 VkDebugReportCallbackEXT callback, 110 const VkAllocationCallbacks* allocator) { 111 if (callback) 112 GetDebugReportCallbacks(instance).DestroyCallback(instance, callback, 113 allocator); 114} 115 116void DebugReportMessageEXT_Bottom(VkInstance instance, 117 VkDebugReportFlagsEXT flags, 118 VkDebugReportObjectTypeEXT object_type, 119 uint64_t object, 120 size_t location, 121 int32_t message_code, 122 const char* layer_prefix, 123 const char* message) { 124 if (GetDriverDispatch(instance).DebugReportMessageEXT) { 125 GetDriverDispatch(instance).DebugReportMessageEXT( 126 GetDriverInstance(instance), flags, object_type, object, location, 127 message_code, layer_prefix, message); 128 } 129 GetDebugReportCallbacks(instance).Message(flags, object_type, object, 130 location, message_code, 131 layer_prefix, message); 132} 133 134} // namespace vulkan 135