Flutter Impeller
debug_report_vk.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 
6 
9 
10 namespace impeller {
11 
13  const vk::Instance& instance) {
14  if (!caps.AreValidationsEnabled()) {
15  is_valid_ = true;
16  return;
17  }
18 
19  vk::DebugUtilsMessengerCreateInfoEXT messenger_info;
20  messenger_info.messageSeverity =
21  vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
22  vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
23  messenger_info.messageType =
24  vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
25  vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
26  vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation;
27  messenger_info.pUserData = this;
28  messenger_info.pfnUserCallback = DebugUtilsMessengerCallback;
29 
30  auto messenger = instance.createDebugUtilsMessengerEXTUnique(messenger_info);
31 
32  if (messenger.result != vk::Result::eSuccess) {
33  FML_LOG(ERROR) << "Could not create debug messenger: "
34  << vk::to_string(messenger.result);
35  return;
36  }
37 
38  messenger_ = std::move(messenger.value);
39  is_valid_ = true;
40 }
41 
43 
44 bool DebugReportVK::IsValid() const {
45  return is_valid_;
46 }
47 
48 static std::string JoinLabels(const VkDebugUtilsLabelEXT* labels,
49  size_t count) {
50  std::stringstream stream;
51  for (size_t i = 0u; i < count; i++) {
52  stream << labels[i].pLabelName;
53  if (i != count - 1u) {
54  stream << ", ";
55  }
56  }
57  return stream.str();
58 }
59 
61  const VkDebugUtilsObjectNameInfoEXT* names,
62  size_t count) {
63  std::stringstream stream;
64  for (size_t i = 0u; i < count; i++) {
65  stream << vk::to_string(vk::ObjectType(names[i].objectType)) << " ["
66  << names[i].objectHandle << "] [";
67  if (names[i].pObjectName != nullptr) {
68  stream << names[i].pObjectName;
69  } else {
70  stream << "UNNAMED";
71  }
72  stream << "]";
73  if (i != count - 1u) {
74  stream << ", ";
75  }
76  }
77  return stream.str();
78 }
79 
80 VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportVK::DebugUtilsMessengerCallback(
81  VkDebugUtilsMessageSeverityFlagBitsEXT severity,
82  VkDebugUtilsMessageTypeFlagsEXT type,
83  const VkDebugUtilsMessengerCallbackDataEXT* callback_data,
84  void* debug_report) {
85  auto result =
86  reinterpret_cast<DebugReportVK*>(debug_report)
87  ->OnDebugCallback(
88  static_cast<vk::DebugUtilsMessageSeverityFlagBitsEXT>(
89  severity), //
90  static_cast<vk::DebugUtilsMessageTypeFlagsEXT>(type), //
91  callback_data //
92  );
93  switch (result) {
94  case Result::kContinue:
95  return VK_FALSE;
96  case Result::kAbort:
97  return VK_TRUE;
98  }
99  return VK_FALSE;
100 }
101 
102 DebugReportVK::Result DebugReportVK::OnDebugCallback(
103  vk::DebugUtilsMessageSeverityFlagBitsEXT severity,
104  vk::DebugUtilsMessageTypeFlagsEXT type,
105  const VkDebugUtilsMessengerCallbackDataEXT* data) {
106  // Issue in older versions of the SDK.
107  // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/3554
108  if (strstr(data->pMessageIdName, "CoreValidation-Shader-OutputNotConsumed") !=
109  nullptr) {
110  return Result::kContinue;
111  }
112 
113  // This is a real error but we can't fix it due to our headers being too
114  // old. More more details see:
115  // https://vulkan.lunarg.com/doc/view/1.3.224.1/mac/1.3-extensions/vkspec.html#VUID-VkImageViewCreateInfo-imageViewFormatSwizzle-04465
116  // This validation error currently only trips on macOS due to the use of
117  // texture swizzles.
118  if (data->messageIdNumber == static_cast<int32_t>(0x82ae5050)) {
119  return Result::kContinue;
120  }
121 
122  std::vector<std::pair<std::string, std::string>> items;
123 
124  items.emplace_back("Severity", vk::to_string(severity));
125 
126  items.emplace_back("Type", vk::to_string(type));
127 
128  if (data->pMessageIdName) {
129  items.emplace_back("ID Name", data->pMessageIdName);
130  }
131 
132  items.emplace_back("ID Number", std::to_string(data->messageIdNumber));
133 
134  if (auto queues = JoinLabels(data->pQueueLabels, data->queueLabelCount);
135  !queues.empty()) {
136  items.emplace_back("Queue Breadcrumbs", std::move(queues));
137  } else {
138  items.emplace_back("Queue Breadcrumbs", "[NONE]");
139  }
140 
141  if (auto cmd_bufs = JoinLabels(data->pCmdBufLabels, data->cmdBufLabelCount);
142  !cmd_bufs.empty()) {
143  items.emplace_back("CMD Buffer Breadcrumbs", std::move(cmd_bufs));
144  } else {
145  items.emplace_back("CMD Buffer Breadcrumbs", "[NONE]");
146  }
147 
148  if (auto related =
149  JoinVKDebugUtilsObjectNameInfoEXT(data->pObjects, data->objectCount);
150  !related.empty()) {
151  items.emplace_back("Related Objects", std::move(related));
152  }
153 
154  if (data->pMessage) {
155  items.emplace_back("Trigger", data->pMessage);
156  }
157 
158  size_t padding = 0;
159 
160  for (const auto& item : items) {
161  padding = std::max(padding, item.first.size());
162  }
163 
164  padding += 1;
165 
166  std::stringstream stream;
167 
168  stream << std::endl;
169 
170  stream << "--- Vulkan Debug Report ----------------------------------------";
171 
172  stream << std::endl;
173 
174  for (const auto& item : items) {
175  stream << "| " << std::setw(static_cast<int>(padding)) << item.first
176  << std::setw(0) << ": " << item.second << std::endl;
177  }
178 
179  stream << "-----------------------------------------------------------------";
180 
181  if (type == vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance) {
182  FML_LOG(INFO) << stream.str();
183  } else {
184  VALIDATION_LOG << stream.str();
185  }
186 
187  return Result::kContinue;
188 }
189 
190 } // namespace impeller
impeller::DebugReportVK::IsValid
bool IsValid() const
Definition: debug_report_vk.cc:44
validation.h
capabilities_vk.h
debug_report_vk.h
impeller::JoinVKDebugUtilsObjectNameInfoEXT
static std::string JoinVKDebugUtilsObjectNameInfoEXT(const VkDebugUtilsObjectNameInfoEXT *names, size_t count)
Definition: debug_report_vk.cc:60
impeller::CapabilitiesVK
The Vulkan layers and extensions wrangler.
Definition: capabilities_vk.h:30
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::DebugReportVK::~DebugReportVK
~DebugReportVK()
impeller::JoinLabels
static std::string JoinLabels(const VkDebugUtilsLabelEXT *labels, size_t count)
Definition: debug_report_vk.cc:48
impeller::CapabilitiesVK::AreValidationsEnabled
bool AreValidationsEnabled() const
Definition: capabilities_vk.cc:61
impeller
Definition: aiks_context.cc:10
impeller::DebugReportVK::DebugReportVK
DebugReportVK(const CapabilitiesVK &caps, const vk::Instance &instance)
Definition: debug_report_vk.cc:12