blob: c4a1174191d62ef85931b9e04609300a35d09a0d [file] [log] [blame]
/*
* Copyright 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "driver.h"
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;
}
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;
}
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);
}
const VkAllocationCallbacks* alloc =
allocator ? allocator : &GetData(instance).allocator;
alloc->pfnFree(alloc->pUserData, node);
}
void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT object_type,
uint64_t object,
size_t location,
int32_t message_code,
const char* layer_prefix,
const char* message) {
std::shared_lock<decltype(rwmutex_)> lock(rwmutex_);
Node* node = &head_;
while ((node = node->next)) {
if ((node->flags & flags) != 0) {
node->callback(flags, object_type, object, location, message_code,
layer_prefix, message, node->data);
}
}
}
VkResult CreateDebugReportCallbackEXT(
VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT* create_info,
const VkAllocationCallbacks* allocator,
VkDebugReportCallbackEXT* callback) {
return GetData(instance).debug_report_callbacks.CreateCallback(
instance, create_info, allocator, callback);
}
void DestroyDebugReportCallbackEXT(VkInstance instance,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks* allocator) {
if (callback)
GetData(instance).debug_report_callbacks.DestroyCallback(
instance, callback, allocator);
}
void DebugReportMessageEXT(VkInstance instance,
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT object_type,
uint64_t object,
size_t location,
int32_t message_code,
const char* layer_prefix,
const char* message) {
if (GetData(instance).driver.DebugReportMessageEXT) {
GetData(instance).driver.DebugReportMessageEXT(
instance, flags, object_type, object, location, message_code,
layer_prefix, message);
}
GetData(instance).debug_report_callbacks.Message(flags, object_type, object,
location, message_code,
layer_prefix, message);
}
} // namespace driver
} // namespace vulkan