1715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall/* 2715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * Copyright 2016 The Android Open Source Project 3715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * 4715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * Licensed under the Apache License, Version 2.0 (the "License"); 5715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * you may not use this file except in compliance with the License. 6715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * You may obtain a copy of the License at 7715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * 8715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * http://www.apache.org/licenses/LICENSE-2.0 9715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * 10715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * Unless required by applicable law or agreed to in writing, software 11715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * distributed under the License is distributed on an "AS IS" BASIS, 12715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * See the License for the specific language governing permissions and 14715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall * limitations under the License. 15715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall */ 16715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 174a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu#include "driver.h" 18715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 19715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hallnamespace vulkan { 20622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wunamespace driver { 21715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 22a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I WuDebugReportCallbackList::Node* DebugReportCallbackList::AddCallback( 23a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu const VkDebugReportCallbackCreateInfoEXT& info, 24a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VkDebugReportCallbackEXT driver_handle, 25a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu const VkAllocationCallbacks& allocator) { 26a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu void* mem = allocator.pfnAllocation(allocator.pUserData, sizeof(Node), 27a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu alignof(Node), 28a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 29a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (!mem) 30a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return nullptr; 31715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 32a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu // initialize and prepend node to the list 33715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall std::lock_guard<decltype(rwmutex_)> lock(rwmutex_); 34a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu head_.next = new (mem) Node{head_.next, info.flags, info.pfnCallback, 35a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu info.pUserData, driver_handle}; 36a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 37a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return head_.next; 38715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 39715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 40a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wuvoid DebugReportCallbackList::RemoveCallback( 41a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu Node* node, 42a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu const VkAllocationCallbacks& allocator) { 43a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu // remove node from the list 44a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu { 45a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu std::lock_guard<decltype(rwmutex_)> lock(rwmutex_); 46a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu Node* prev = &head_; 47a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu while (prev && prev->next != node) 48a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu prev = prev->next; 49a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu prev->next = node->next; 506fecdd563f3bf94dadedc78512a1b28c08c67e07Courtney Goeltzenleuchter } 51715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 52a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu allocator.pfnFree(allocator.pUserData, node); 53715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 54715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 55715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hallvoid DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, 56715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall VkDebugReportObjectTypeEXT object_type, 57715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall uint64_t object, 58715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall size_t location, 59715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall int32_t message_code, 60715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall const char* layer_prefix, 61b3055f34650cd066a349e1e8cba294b05513ef2eChia-I Wu const char* message) const { 62715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall std::shared_lock<decltype(rwmutex_)> lock(rwmutex_); 63b3055f34650cd066a349e1e8cba294b05513ef2eChia-I Wu const Node* node = &head_; 64715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall while ((node = node->next)) { 65715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall if ((node->flags & flags) != 0) { 66715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall node->callback(flags, object_type, object, location, message_code, 67a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu layer_prefix, message, node->user_data); 68715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall } 69715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall } 70715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 71715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 72bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wuvoid DebugReportLogger::Message(VkDebugReportFlagsEXT flags, 73bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu VkDebugReportObjectTypeEXT object_type, 74bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu uint64_t object, 75bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu size_t location, 76bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu int32_t message_code, 77bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu const char* layer_prefix, 78bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu const char* message) const { 79bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu const VkDebugReportCallbackCreateInfoEXT* info = 80bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT*>( 81bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu instance_pnext_); 82bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu while (info) { 832676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall if (info->sType == 842676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT && 85ede02ac245b5f2aa1139d6cb0e2dc7c0f8f290d2Chia-I Wu (info->flags & flags) != 0) { 86bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu info->pfnCallback(flags, object_type, object, location, 87bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu message_code, layer_prefix, message, 88bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu info->pUserData); 89bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu } 90bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 91bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu info = reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT*>( 92bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu info->pNext); 93bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu } 94bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 95bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu if (callbacks_) { 96bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu callbacks_->Message(flags, object_type, object, location, message_code, 97bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu layer_prefix, message); 98bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu } 99bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu} 100bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 101bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wuvoid DebugReportLogger::PrintV(VkDebugReportFlagsEXT flags, 102bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu VkDebugReportObjectTypeEXT object_type, 103bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu uint64_t object, 104bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu const char* format, 105bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu va_list ap) const { 106bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu char buf[1024]; 107bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu int len = vsnprintf(buf, sizeof(buf), format, ap); 108bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 109bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu // message truncated 110bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu if (len >= static_cast<int>(sizeof(buf))) 111bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu memcpy(buf + sizeof(buf) - 4, "...", 4); 112bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 113bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu Message(flags, object_type, object, 0, 0, LOG_TAG, buf); 114bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu} 115bc011fc4d78442d1f0167b04aea3484c62e0a92bChia-I Wu 116622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateDebugReportCallbackEXT( 117715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall VkInstance instance, 118715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall const VkDebugReportCallbackCreateInfoEXT* create_info, 119715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall const VkAllocationCallbacks* allocator, 120715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall VkDebugReportCallbackEXT* callback) { 121a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu const auto& driver = GetData(instance).driver; 122a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VkDebugReportCallbackEXT driver_handle = VK_NULL_HANDLE; 123a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver.CreateDebugReportCallbackEXT) { 124a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VkResult result = driver.CreateDebugReportCallbackEXT( 125a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu instance, create_info, allocator, &driver_handle); 126a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (result != VK_SUCCESS) 127a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return result; 128a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 129a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 130a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto& callbacks = GetData(instance).debug_report_callbacks; 131a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto node = callbacks.AddCallback( 132a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu *create_info, driver_handle, 133a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu (allocator) ? *allocator : GetData(instance).allocator); 134a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (!node) { 135a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver_handle != VK_NULL_HANDLE) { 136a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu driver.DestroyDebugReportCallbackEXT(instance, driver_handle, 137a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu allocator); 138a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 139a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 140a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 141a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 142a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 143a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu *callback = callbacks.GetHandle(node); 144a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 145a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return VK_SUCCESS; 146715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 147715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 148622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroyDebugReportCallbackEXT(VkInstance instance, 149622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportCallbackEXT callback, 150622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 151a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (callback == VK_NULL_HANDLE) 152a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return; 153a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 154a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto& callbacks = GetData(instance).debug_report_callbacks; 155a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto node = callbacks.FromHandle(callback); 156a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto driver_handle = callbacks.GetDriverHandle(node); 157a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 158a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu callbacks.RemoveCallback( 159a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu node, (allocator) ? *allocator : GetData(instance).allocator); 160a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 161a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver_handle != VK_NULL_HANDLE) { 162a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu GetData(instance).driver.DestroyDebugReportCallbackEXT( 163a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu instance, driver_handle, allocator); 164a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 165715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 166715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 167622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DebugReportMessageEXT(VkInstance instance, 168622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportFlagsEXT flags, 169622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportObjectTypeEXT object_type, 170622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint64_t object, 171622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu size_t location, 172622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu int32_t message_code, 173622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const char* layer_prefix, 174622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const char* message) { 1754a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu if (GetData(instance).driver.DebugReportMessageEXT) { 1764a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu GetData(instance).driver.DebugReportMessageEXT( 1774a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu instance, flags, object_type, object, location, message_code, 1784a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu layer_prefix, message); 1792e6736699471dbe7ec185667240089dcbccdd9bdChia-I Wu } else { 1802e6736699471dbe7ec185667240089dcbccdd9bdChia-I Wu GetData(instance).debug_report_callbacks.Message( 1812e6736699471dbe7ec185667240089dcbccdd9bdChia-I Wu flags, object_type, object, location, message_code, layer_prefix, 1822e6736699471dbe7ec185667240089dcbccdd9bdChia-I Wu message); 1836fecdd563f3bf94dadedc78512a1b28c08c67e07Courtney Goeltzenleuchter } 184715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 185715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 186622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu} // namespace driver 187715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} // namespace vulkan 188