debug_report.cpp revision 622622377a1ac71a81a88e335f170c4a08835f06
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 { 20namespace driver { 21 22VkResult DebugReportCallbackList::CreateCallback( 23 VkInstance instance, 24 const VkDebugReportCallbackCreateInfoEXT* create_info, 25 const VkAllocationCallbacks* allocator, 26 VkDebugReportCallbackEXT* callback) { 27 VkDebugReportCallbackEXT driver_callback = VK_NULL_HANDLE; 28 29 if (GetDriverDispatch(instance).CreateDebugReportCallbackEXT) { 30 VkResult result = 31 GetDriverDispatch(instance).CreateDebugReportCallbackEXT( 32 GetDriverInstance(instance), create_info, allocator, 33 &driver_callback); 34 if (result != VK_SUCCESS) 35 return result; 36 } 37 38 const VkAllocationCallbacks* alloc = 39 allocator ? allocator : GetAllocator(instance); 40 void* mem = 41 alloc->pfnAllocation(alloc->pUserData, sizeof(Node), alignof(Node), 42 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 43 if (!mem) { 44 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { 45 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( 46 GetDriverInstance(instance), driver_callback, allocator); 47 } 48 return VK_ERROR_OUT_OF_HOST_MEMORY; 49 } 50 51 std::lock_guard<decltype(rwmutex_)> lock(rwmutex_); 52 head_.next = 53 new (mem) Node{head_.next, create_info->flags, create_info->pfnCallback, 54 create_info->pUserData, driver_callback}; 55 *callback = 56 VkDebugReportCallbackEXT(reinterpret_cast<uintptr_t>(head_.next)); 57 return VK_SUCCESS; 58} 59 60void DebugReportCallbackList::DestroyCallback( 61 VkInstance instance, 62 VkDebugReportCallbackEXT callback, 63 const VkAllocationCallbacks* allocator) { 64 Node* node = reinterpret_cast<Node*>(uintptr_t(callback)); 65 std::unique_lock<decltype(rwmutex_)> lock(rwmutex_); 66 Node* prev = &head_; 67 while (prev && prev->next != node) 68 prev = prev->next; 69 prev->next = node->next; 70 lock.unlock(); 71 72 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) { 73 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT( 74 GetDriverInstance(instance), node->driver_callback, allocator); 75 } 76 77 const VkAllocationCallbacks* alloc = 78 allocator ? allocator : GetAllocator(instance); 79 alloc->pfnFree(alloc->pUserData, node); 80} 81 82void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, 83 VkDebugReportObjectTypeEXT object_type, 84 uint64_t object, 85 size_t location, 86 int32_t message_code, 87 const char* layer_prefix, 88 const char* message) { 89 std::shared_lock<decltype(rwmutex_)> lock(rwmutex_); 90 Node* node = &head_; 91 while ((node = node->next)) { 92 if ((node->flags & flags) != 0) { 93 node->callback(flags, object_type, object, location, message_code, 94 layer_prefix, message, node->data); 95 } 96 } 97} 98 99VkResult CreateDebugReportCallbackEXT( 100 VkInstance instance, 101 const VkDebugReportCallbackCreateInfoEXT* create_info, 102 const VkAllocationCallbacks* allocator, 103 VkDebugReportCallbackEXT* callback) { 104 return GetDebugReportCallbacks(instance).CreateCallback( 105 instance, create_info, allocator, callback); 106} 107 108void DestroyDebugReportCallbackEXT(VkInstance instance, 109 VkDebugReportCallbackEXT callback, 110 const VkAllocationCallbacks* allocator) { 111 if (callback) 112 GetDebugReportCallbacks(instance).DestroyCallback(instance, callback, 113 allocator); 114} 115 116void DebugReportMessageEXT(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 driver 135} // namespace vulkan 136