Flutter Engine
vulkan_debug_report.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "vulkan_debug_report.h"
6 
7 #include <iomanip>
8 #include <vector>
9 
10 #include "flutter/fml/compiler_specific.h"
11 #include "vulkan_utilities.h"
12 
13 namespace vulkan {
14 
15 static const VkDebugReportFlagsEXT kVulkanErrorFlags FML_ALLOW_UNUSED_TYPE =
16  VK_DEBUG_REPORT_WARNING_BIT_EXT |
17  VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;
18 
19 static const VkDebugReportFlagsEXT kVulkanInfoFlags FML_ALLOW_UNUSED_TYPE =
20  VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;
21 
23  return VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
24 }
25 
26 static const char* VkDebugReportFlagsEXTToString(VkDebugReportFlagsEXT flags) {
27  if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
28  return "Information";
29  } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
30  return "Warning";
31  } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
32  return "Performance Warning";
33  } else if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
34  return "Error";
35  } else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
36  return "Debug";
37  }
38  return "UNKNOWN";
39 }
40 
42  VkDebugReportObjectTypeEXT type) {
43  switch (type) {
44  case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT:
45  return "Unknown";
46  case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT:
47  return "Instance";
48  case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT:
49  return "Physical Device";
50  case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT:
51  return "Device";
52  case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT:
53  return "Queue";
54  case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT:
55  return "Semaphore";
56  case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT:
57  return "Command Buffer";
58  case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT:
59  return "Fence";
60  case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT:
61  return "Device Memory";
62  case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
63  return "Buffer";
64  case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
65  return "Image";
66  case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT:
67  return "Event";
68  case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT:
69  return "Query Pool";
70  case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT:
71  return "Buffer View";
72  case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT:
73  return "Image_view";
74  case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT:
75  return "Shader Module";
76  case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT:
77  return "Pipeline Cache";
78  case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT:
79  return "Pipeline Layout";
80  case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT:
81  return "Render Pass";
82  case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT:
83  return "Pipeline";
84  case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT:
85  return "Descriptor Set Layout";
86  case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT:
87  return "Sampler";
88  case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT:
89  return "Descriptor Pool";
90  case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT:
91  return "Descriptor Set";
92  case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT:
93  return "Framebuffer";
94  case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT:
95  return "Command Pool";
96  case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT:
97  return "Surface";
98  case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
99  return "Swapchain";
100  case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT:
101  return "Debug";
102  default:
103  break;
104  }
105 
106  return "Unknown";
107 }
108 
109 static VKAPI_ATTR VkBool32
110 OnVulkanDebugReportCallback(VkDebugReportFlagsEXT flags,
111  VkDebugReportObjectTypeEXT object_type,
112  uint64_t object,
113  size_t location,
114  int32_t message_code,
115  const char* layer_prefix,
116  const char* message,
117  void* user_data) {
118  std::vector<std::pair<std::string, std::string>> items;
119 
120  items.emplace_back("Severity", VkDebugReportFlagsEXTToString(flags));
121 
122  items.emplace_back("Object Type",
124 
125  items.emplace_back("Object Handle", std::to_string(object));
126 
127  if (location != 0) {
128  items.emplace_back("Location", std::to_string(location));
129  }
130 
131  if (message_code != 0) {
132  items.emplace_back("Message Code", std::to_string(message_code));
133  }
134 
135  if (layer_prefix != nullptr) {
136  items.emplace_back("Layer", layer_prefix);
137  }
138 
139  if (message != nullptr) {
140  items.emplace_back("Message", message);
141  }
142 
143  size_t padding = 0;
144 
145  for (const auto& item : items) {
146  padding = std::max(padding, item.first.size());
147  }
148 
149  padding += 1;
150 
151  std::stringstream stream;
152 
153  stream << std::endl;
154 
155  stream << "--- Vulkan Debug Report ----------------------------------------";
156 
157  stream << std::endl;
158 
159  for (const auto& item : items) {
160  stream << "| " << std::setw(static_cast<int>(padding)) << item.first
161  << std::setw(0) << ": " << item.second << std::endl;
162  }
163 
164  stream << "-----------------------------------------------------------------";
165 
166  if (flags & kVulkanErrorFlags) {
167  if (ValidationErrorsFatal()) {
168  FML_DCHECK(false) << stream.str();
169  } else {
170  FML_LOG(ERROR) << stream.str();
171  }
172  } else {
173  FML_LOG(INFO) << stream.str();
174  }
175 
176  // Returning false tells the layer not to stop when the event occurs, so
177  // they see the same behavior with and without validation layers enabled.
178  return VK_FALSE;
179 }
180 
182  const VulkanProcTable& p_vk,
183  const VulkanHandle<VkInstance>& application)
184  : vk(p_vk), application_(application), valid_(false) {
185  if (!vk.CreateDebugReportCallbackEXT || !vk.DestroyDebugReportCallbackEXT) {
186  return;
187  }
188 
189  if (!application_) {
190  return;
191  }
192 
193  VkDebugReportFlagsEXT flags = kVulkanErrorFlags;
195  flags |= kVulkanInfoFlags;
196  }
197  const VkDebugReportCallbackCreateInfoEXT create_info = {
198  .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
199  .pNext = nullptr,
200  .flags = flags,
201  .pfnCallback = &vulkan::OnVulkanDebugReportCallback,
202  .pUserData = nullptr,
203  };
204 
205  VkDebugReportCallbackEXT handle = VK_NULL_HANDLE;
206  if (VK_CALL_LOG_ERROR(vk.CreateDebugReportCallbackEXT(
207  application_, &create_info, nullptr, &handle)) != VK_SUCCESS) {
208  return;
209  }
210 
211  handle_ = {handle, [this](VkDebugReportCallbackEXT handle) {
212  vk.DestroyDebugReportCallbackEXT(application_, handle, nullptr);
213  }};
214 
215  valid_ = true;
216 }
217 
219 
221  return valid_;
222 }
223 
224 } // namespace vulkan
#define FML_DCHECK(condition)
Definition: logging.h:86
static const char * VkDebugReportFlagsEXTToString(VkDebugReportFlagsEXT flags)
static const VkDebugReportFlagsEXT kVulkanErrorFlags FML_ALLOW_UNUSED_TYPE
#define FML_LOG(severity)
Definition: logging.h:65
static const char * VkDebugReportObjectTypeEXTToString(VkDebugReportObjectTypeEXT type)
bool ValidationLayerInfoMessagesEnabled()
G_BEGIN_DECLS FlValue gpointer user_data
bool ValidationErrorsFatal()
#define VK_CALL_LOG_ERROR(expression)
VulkanDebugReport(const VulkanProcTable &vk, const VulkanHandle< VkInstance > &application)
static std::string DebugExtensionName()
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66
static VKAPI_ATTR VkBool32 OnVulkanDebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, uint64_t object, size_t location, int32_t message_code, const char *layer_prefix, const char *message, void *user_data)