debug_report.cpp revision b3055f34650cd066a349e1e8cba294b05513ef2e
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 72622622377a1ac71a81a88e335f170c4a08835f06Chia-I WuVkResult CreateDebugReportCallbackEXT( 73715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall VkInstance instance, 74715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall const VkDebugReportCallbackCreateInfoEXT* create_info, 75715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall const VkAllocationCallbacks* allocator, 76715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall VkDebugReportCallbackEXT* callback) { 77a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu const auto& driver = GetData(instance).driver; 78a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VkDebugReportCallbackEXT driver_handle = VK_NULL_HANDLE; 79a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver.CreateDebugReportCallbackEXT) { 80a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu VkResult result = driver.CreateDebugReportCallbackEXT( 81a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu instance, create_info, allocator, &driver_handle); 82a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (result != VK_SUCCESS) 83a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return result; 84a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 85a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 86a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto& callbacks = GetData(instance).debug_report_callbacks; 87a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto node = callbacks.AddCallback( 88a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu *create_info, driver_handle, 89a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu (allocator) ? *allocator : GetData(instance).allocator); 90a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (!node) { 91a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver_handle != VK_NULL_HANDLE) { 92a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu driver.DestroyDebugReportCallbackEXT(instance, driver_handle, 93a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu allocator); 94a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 95a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 96a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return VK_ERROR_OUT_OF_HOST_MEMORY; 97a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 98a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 99a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu *callback = callbacks.GetHandle(node); 100a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 101a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return VK_SUCCESS; 102715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 103715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 104622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DestroyDebugReportCallbackEXT(VkInstance instance, 105622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportCallbackEXT callback, 106622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const VkAllocationCallbacks* allocator) { 107a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (callback == VK_NULL_HANDLE) 108a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu return; 109a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 110a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto& callbacks = GetData(instance).debug_report_callbacks; 111a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto node = callbacks.FromHandle(callback); 112a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu auto driver_handle = callbacks.GetDriverHandle(node); 113a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 114a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu callbacks.RemoveCallback( 115a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu node, (allocator) ? *allocator : GetData(instance).allocator); 116a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu 117a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu if (driver_handle != VK_NULL_HANDLE) { 118a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu GetData(instance).driver.DestroyDebugReportCallbackEXT( 119a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu instance, driver_handle, allocator); 120a0d40aaf12435fe82bc9c1612dbe97ea2a60da31Chia-I Wu } 121715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 122715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 123622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wuvoid DebugReportMessageEXT(VkInstance instance, 124622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportFlagsEXT flags, 125622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu VkDebugReportObjectTypeEXT object_type, 126622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu uint64_t object, 127622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu size_t location, 128622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu int32_t message_code, 129622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const char* layer_prefix, 130622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu const char* message) { 1314a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu if (GetData(instance).driver.DebugReportMessageEXT) { 1324a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu GetData(instance).driver.DebugReportMessageEXT( 1334a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu instance, flags, object_type, object, location, message_code, 1344a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu layer_prefix, message); 1356fecdd563f3bf94dadedc78512a1b28c08c67e07Courtney Goeltzenleuchter } 1364a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu GetData(instance).debug_report_callbacks.Message(flags, object_type, object, 1374a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu location, message_code, 1384a6a91647c57abb5c06cde57c57afe944f8cefa4Chia-I Wu layer_prefix, message); 139715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} 140715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall 141622622377a1ac71a81a88e335f170c4a08835f06Chia-I Wu} // namespace driver 142715b86ac7d0853131b375ff786c87d8d87a762a1Jesse Hall} // namespace vulkan 143