blob: 41b604063b7512faadb1562a81f59fc98e3f4f42 [file] [log] [blame]
Jesse Hall715b86a2016-01-16 16:34:29 -08001/*
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) {
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -070026 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 }
Jesse Hall715b86a2016-01-16 16:34:29 -080036
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) {
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -070043 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) {
44 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT(
45 GetDriverInstance(instance), driver_callback, allocator);
46 }
Jesse Hall715b86a2016-01-16 16:34:29 -080047 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
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -070071 if (GetDriverDispatch(instance).DestroyDebugReportCallbackEXT) {
72 GetDriverDispatch(instance).DestroyDebugReportCallbackEXT(
73 GetDriverInstance(instance), node->driver_callback, allocator);
74 }
Jesse Hall715b86a2016-01-16 16:34:29 -080075
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) {
Courtney Goeltzenleuchter6fecdd52016-02-03 15:14:46 -0700124 if (GetDriverDispatch(instance).DebugReportMessageEXT) {
125 GetDriverDispatch(instance).DebugReportMessageEXT(
126 GetDriverInstance(instance), flags, object_type, object, location,
127 message_code, layer_prefix, message);
128 }
Jesse Hall715b86a2016-01-16 16:34:29 -0800129 GetDebugReportCallbacks(instance).Message(flags, object_type, object,
130 location, message_code,
131 layer_prefix, message);
132}
133
134} // namespace vulkan