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