Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e442370

Browse files
authored
vulkan_glfw validation layer logging (#54607)
This PR enables printing validation output when the Vulkan validation layer is enabled. Without this change no messages are printed which provides a false positive for the Vulkan Embedder API health. *List which issues are fixed by this PR. You must list at least one issue.* flutter/flutter#153663 *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style cc @chinmaygarde Fixes flutter/flutter#153663
1 parent 1a2360f commit e442370

File tree

2 files changed

+124
-17
lines changed

2 files changed

+124
-17
lines changed

examples/vulkan_glfw/run.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ if [ ! -d myapp ]; then
1515
flutter create myapp
1616
fi
1717
pushd myapp > /dev/null
18-
#cp ../../main.dart lib/main.dart
18+
flutter pub add flutter_gpu --sdk=flutter
19+
cp ../../../glfw/main.dart lib/main.dart
1920
flutter build bundle \
2021
--local-engine-src-path ../../../../../ \
2122
--local-engine=host_debug_unopt \

examples/vulkan_glfw/src/main.cc

+122-16
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
#include "vulkan/vulkan.hpp"
1616
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
1717

18+
#define S1(x) #x
19+
#define S2(x) S1(x)
20+
#define LOCATION __FILE__ " : " S2(__LINE__)
21+
22+
#define CHECK_VK_RESULT(x) \
23+
do { \
24+
vk::resultCheck(static_cast<vk::Result>(x), LOCATION); \
25+
} while (0)
26+
1827
// Convenient reference to vulkan.hpp's global proc table.
1928
auto& d = vk::defaultDispatchLoaderDynamic;
2029

@@ -23,7 +32,13 @@ auto& d = vk::defaultDispatchLoaderDynamic;
2332

2433
#include "embedder.h" // Flutter's Embedder ABI.
2534

26-
static const bool g_enable_validation_layers = true;
35+
struct {
36+
bool enable_validation_layers = true;
37+
bool utils_supported = false;
38+
bool report_supported = false;
39+
VkDebugReportCallbackEXT report_callback = VK_NULL_HANDLE;
40+
VkDebugUtilsMessengerEXT utils_messenger_callback = VK_NULL_HANDLE;
41+
} g_debug;
2742
// This value is calculated after the window is created.
2843
static double g_pixelRatio = 1.0;
2944
static const size_t kInitialWindowWidth = 800;
@@ -45,6 +60,7 @@ struct {
4560
GLFWwindow* window;
4661

4762
std::vector<const char*> enabled_instance_extensions;
63+
std::vector<const char*> enabled_layer_names;
4864
VkInstance instance;
4965
VkSurfaceKHR surface;
5066

@@ -404,6 +420,56 @@ void* FlutterGetInstanceProcAddressCallback(
404420
return reinterpret_cast<void*>(proc);
405421
}
406422

423+
VkBool32 DebugReportCallback(VkDebugReportFlagsEXT flags,
424+
VkDebugReportObjectTypeEXT /* objectType */,
425+
uint64_t /* object */,
426+
size_t /* location */,
427+
int32_t /* messageCode */,
428+
const char* pLayerPrefix,
429+
const char* pMessage,
430+
void* /* pUserData */) {
431+
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
432+
std::cout << "VULKAN: (" << pLayerPrefix << ") " << pMessage << std::endl;
433+
} else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
434+
std::cout << "VULKAN DEBUG: (" << pLayerPrefix << ") " << pMessage
435+
<< std::endl;
436+
} else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
437+
std::cout << "VULKAN PERF WARNING: (" << pLayerPrefix << ") " << pMessage
438+
<< std::endl;
439+
} else if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
440+
std::cerr << "VULKAN ERROR: (" << pLayerPrefix << ") " << pMessage
441+
<< std::endl;
442+
} else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
443+
std::cout << "VULKAN DEBUG: (" << pLayerPrefix << ") " << pMessage
444+
<< std::endl;
445+
}
446+
return VK_FALSE;
447+
}
448+
449+
VkBool32 DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
450+
VkDebugUtilsMessageTypeFlagsEXT /* types */,
451+
const VkDebugUtilsMessengerCallbackDataEXT* cb_data,
452+
void* /* pUserData */) {
453+
if (strstr(cb_data->pMessage, "ALL_GRAPHICS_BIT") ||
454+
strstr(cb_data->pMessage, "ALL_COMMANDS_BIT")) {
455+
return VK_FALSE;
456+
}
457+
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
458+
std::cout << "VULKAN: (" << cb_data->pMessageIdName << ") "
459+
<< cb_data->pMessage << std::endl;
460+
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
461+
std::cout << "VULKAN INFO: (" << cb_data->pMessageIdName << ") "
462+
<< cb_data->pMessage << std::endl;
463+
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
464+
std::cout << "VULKAN WARN: (" << cb_data->pMessageIdName << ") "
465+
<< cb_data->pMessage << std::endl;
466+
} else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
467+
std::cerr << "VULKAN ERROR: (" << cb_data->pMessageIdName << ") "
468+
<< cb_data->pMessage << std::endl;
469+
}
470+
return VK_TRUE;
471+
}
472+
407473
int main(int argc, char** argv) {
408474
if (argc != 3) {
409475
PrintUsage();
@@ -473,16 +539,50 @@ int main(int argc, char** argv) {
473539
memcpy(g_state.enabled_instance_extensions.data(), glfw_extensions,
474540
extension_count * sizeof(char*));
475541

476-
if (g_enable_validation_layers) {
477-
g_state.enabled_instance_extensions.push_back(
478-
VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
542+
if (g_debug.enable_validation_layers) {
543+
auto props = vk::enumerateInstanceExtensionProperties();
544+
for (const auto& prop : props.value) {
545+
if (strcmp(prop.extensionName,
546+
VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME) == 0) {
547+
g_state.enabled_instance_extensions.push_back(
548+
VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME);
549+
}
550+
if (strcmp(prop.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) ==
551+
0) {
552+
g_debug.utils_supported = true;
553+
}
554+
if (strcmp(prop.extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) ==
555+
0) {
556+
g_debug.report_supported = true;
557+
}
558+
}
559+
if (g_debug.utils_supported) {
560+
g_state.enabled_instance_extensions.push_back(
561+
VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
562+
g_debug.report_supported = false;
563+
} else if (g_debug.report_supported) {
564+
g_state.enabled_instance_extensions.push_back(
565+
VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
566+
}
567+
568+
auto available_layers = vk::enumerateInstanceLayerProperties();
569+
for (const auto& l : available_layers.value) {
570+
if (strcmp(l.layerName, "VK_LAYER_KHRONOS_validation") == 0) {
571+
g_state.enabled_layer_names.push_back("VK_LAYER_KHRONOS_validation");
572+
}
573+
}
479574
}
480575

481576
std::cout << "Enabling " << g_state.enabled_instance_extensions.size()
482577
<< " instance extensions:" << std::endl;
483578
for (const auto& extension : g_state.enabled_instance_extensions) {
484579
std::cout << " - " << extension << std::endl;
485580
}
581+
std::cout << "Enabling " << g_state.enabled_layer_names.size()
582+
<< " layers:" << std::endl;
583+
for (const auto& layer : g_state.enabled_layer_names) {
584+
std::cout << " - " << layer << std::endl;
585+
}
486586

487587
VkApplicationInfo app_info = {
488588
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
@@ -499,18 +599,8 @@ int main(int argc, char** argv) {
499599
info.pApplicationInfo = &app_info;
500600
info.enabledExtensionCount = g_state.enabled_instance_extensions.size();
501601
info.ppEnabledExtensionNames = g_state.enabled_instance_extensions.data();
502-
if (g_enable_validation_layers) {
503-
auto available_layers = vk::enumerateInstanceLayerProperties();
504-
505-
const char* layer = "VK_LAYER_KHRONOS_validation";
506-
for (const auto& l : available_layers.value) {
507-
if (strcmp(l.layerName, layer) == 0) {
508-
info.enabledLayerCount = 1;
509-
info.ppEnabledLayerNames = &layer;
510-
break;
511-
}
512-
}
513-
}
602+
info.enabledLayerCount = g_state.enabled_layer_names.size();
603+
info.ppEnabledLayerNames = g_state.enabled_layer_names.data();
514604

515605
if (d.vkCreateInstance(&info, nullptr, &g_state.instance) != VK_SUCCESS) {
516606
std::cerr << "Failed to create Vulkan instance." << std::endl;
@@ -798,8 +888,24 @@ int main(int argc, char** argv) {
798888
nullptr);
799889
d.vkDestroyFence(g_state.device, g_state.image_ready_fence, nullptr);
800890

891+
if (g_state.swapchain) {
892+
d.vkDestroySwapchainKHR(g_state.device, g_state.swapchain, nullptr);
893+
}
894+
801895
d.vkDestroyDevice(g_state.device, nullptr);
802896
d.vkDestroySurfaceKHR(g_state.instance, g_state.surface, nullptr);
897+
898+
if (g_debug.enable_validation_layers) {
899+
if (g_debug.report_callback) {
900+
d.vkDestroyDebugReportCallbackEXT(g_state.instance,
901+
g_debug.report_callback, nullptr);
902+
}
903+
if (g_debug.utils_messenger_callback) {
904+
d.vkDestroyDebugUtilsMessengerEXT(
905+
g_state.instance, g_debug.utils_messenger_callback, nullptr);
906+
}
907+
}
908+
803909
d.vkDestroyInstance(g_state.instance, nullptr);
804910

805911
glfwDestroyWindow(g_state.window);

0 commit comments

Comments
 (0)