namespace vulkan {
namespace driver {
-VkResult DebugReportCallbackList::CreateCallback(
- VkInstance instance,
- const VkDebugReportCallbackCreateInfoEXT* create_info,
- const VkAllocationCallbacks* allocator,
- VkDebugReportCallbackEXT* callback) {
- VkDebugReportCallbackEXT driver_callback = VK_NULL_HANDLE;
-
- if (GetData(instance).driver.CreateDebugReportCallbackEXT) {
- VkResult result = GetData(instance).driver.CreateDebugReportCallbackEXT(
- instance, create_info, allocator, &driver_callback);
- if (result != VK_SUCCESS)
- return result;
- }
-
- const VkAllocationCallbacks* alloc =
- allocator ? allocator : &GetData(instance).allocator;
- void* mem =
- alloc->pfnAllocation(alloc->pUserData, sizeof(Node), alignof(Node),
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!mem) {
- if (GetData(instance).driver.DestroyDebugReportCallbackEXT) {
- GetData(instance).driver.DestroyDebugReportCallbackEXT(
- instance, driver_callback, allocator);
- }
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
+DebugReportCallbackList::Node* DebugReportCallbackList::AddCallback(
+ const VkDebugReportCallbackCreateInfoEXT& info,
+ VkDebugReportCallbackEXT driver_handle,
+ const VkAllocationCallbacks& allocator) {
+ void* mem = allocator.pfnAllocation(allocator.pUserData, sizeof(Node),
+ alignof(Node),
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!mem)
+ return nullptr;
+ // initialize and prepend node to the list
std::lock_guard<decltype(rwmutex_)> lock(rwmutex_);
- head_.next =
- new (mem) Node{head_.next, create_info->flags, create_info->pfnCallback,
- create_info->pUserData, driver_callback};
- *callback =
- VkDebugReportCallbackEXT(reinterpret_cast<uintptr_t>(head_.next));
- return VK_SUCCESS;
+ head_.next = new (mem) Node{head_.next, info.flags, info.pfnCallback,
+ info.pUserData, driver_handle};
+
+ return head_.next;
}
-void DebugReportCallbackList::DestroyCallback(
- VkInstance instance,
- VkDebugReportCallbackEXT callback,
- const VkAllocationCallbacks* allocator) {
- Node* node = reinterpret_cast<Node*>(uintptr_t(callback));
- std::unique_lock<decltype(rwmutex_)> lock(rwmutex_);
- Node* prev = &head_;
- while (prev && prev->next != node)
- prev = prev->next;
- prev->next = node->next;
- lock.unlock();
-
- if (GetData(instance).driver.DestroyDebugReportCallbackEXT) {
- GetData(instance).driver.DestroyDebugReportCallbackEXT(
- instance, node->driver_callback, allocator);
+void DebugReportCallbackList::RemoveCallback(
+ Node* node,
+ const VkAllocationCallbacks& allocator) {
+ // remove node from the list
+ {
+ std::lock_guard<decltype(rwmutex_)> lock(rwmutex_);
+ Node* prev = &head_;
+ while (prev && prev->next != node)
+ prev = prev->next;
+ prev->next = node->next;
}
- const VkAllocationCallbacks* alloc =
- allocator ? allocator : &GetData(instance).allocator;
- alloc->pfnFree(alloc->pUserData, node);
+ allocator.pfnFree(allocator.pUserData, node);
}
void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags,
while ((node = node->next)) {
if ((node->flags & flags) != 0) {
node->callback(flags, object_type, object, location, message_code,
- layer_prefix, message, node->data);
+ layer_prefix, message, node->user_data);
}
}
}
const VkDebugReportCallbackCreateInfoEXT* create_info,
const VkAllocationCallbacks* allocator,
VkDebugReportCallbackEXT* callback) {
- return GetData(instance).debug_report_callbacks.CreateCallback(
- instance, create_info, allocator, callback);
+ const auto& driver = GetData(instance).driver;
+ VkDebugReportCallbackEXT driver_handle = VK_NULL_HANDLE;
+ if (driver.CreateDebugReportCallbackEXT) {
+ VkResult result = driver.CreateDebugReportCallbackEXT(
+ instance, create_info, allocator, &driver_handle);
+ if (result != VK_SUCCESS)
+ return result;
+ }
+
+ auto& callbacks = GetData(instance).debug_report_callbacks;
+ auto node = callbacks.AddCallback(
+ *create_info, driver_handle,
+ (allocator) ? *allocator : GetData(instance).allocator);
+ if (!node) {
+ if (driver_handle != VK_NULL_HANDLE) {
+ driver.DestroyDebugReportCallbackEXT(instance, driver_handle,
+ allocator);
+ }
+
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+
+ *callback = callbacks.GetHandle(node);
+
+ return VK_SUCCESS;
}
void DestroyDebugReportCallbackEXT(VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks* allocator) {
- if (callback)
- GetData(instance).debug_report_callbacks.DestroyCallback(
- instance, callback, allocator);
+ if (callback == VK_NULL_HANDLE)
+ return;
+
+ auto& callbacks = GetData(instance).debug_report_callbacks;
+ auto node = callbacks.FromHandle(callback);
+ auto driver_handle = callbacks.GetDriverHandle(node);
+
+ callbacks.RemoveCallback(
+ node, (allocator) ? *allocator : GetData(instance).allocator);
+
+ if (driver_handle != VK_NULL_HANDLE) {
+ GetData(instance).driver.DestroyDebugReportCallbackEXT(
+ instance, driver_handle, allocator);
+ }
}
void DebugReportMessageEXT(VkInstance instance,