15
15
#include " vulkan/vulkan.hpp"
16
16
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
17
17
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
+
18
27
// Convenient reference to vulkan.hpp's global proc table.
19
28
auto & d = vk::defaultDispatchLoaderDynamic;
20
29
@@ -23,7 +32,13 @@ auto& d = vk::defaultDispatchLoaderDynamic;
23
32
24
33
#include " embedder.h" // Flutter's Embedder ABI.
25
34
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;
27
42
// This value is calculated after the window is created.
28
43
static double g_pixelRatio = 1.0 ;
29
44
static const size_t kInitialWindowWidth = 800 ;
@@ -45,6 +60,7 @@ struct {
45
60
GLFWwindow* window;
46
61
47
62
std::vector<const char *> enabled_instance_extensions;
63
+ std::vector<const char *> enabled_layer_names;
48
64
VkInstance instance;
49
65
VkSurfaceKHR surface;
50
66
@@ -404,6 +420,56 @@ void* FlutterGetInstanceProcAddressCallback(
404
420
return reinterpret_cast <void *>(proc);
405
421
}
406
422
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
+
407
473
int main (int argc, char ** argv) {
408
474
if (argc != 3 ) {
409
475
PrintUsage ();
@@ -473,16 +539,50 @@ int main(int argc, char** argv) {
473
539
memcpy (g_state.enabled_instance_extensions .data (), glfw_extensions,
474
540
extension_count * sizeof (char *));
475
541
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
+ }
479
574
}
480
575
481
576
std::cout << " Enabling " << g_state.enabled_instance_extensions .size ()
482
577
<< " instance extensions:" << std::endl;
483
578
for (const auto & extension : g_state.enabled_instance_extensions ) {
484
579
std::cout << " - " << extension << std::endl;
485
580
}
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
+ }
486
586
487
587
VkApplicationInfo app_info = {
488
588
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
@@ -499,18 +599,8 @@ int main(int argc, char** argv) {
499
599
info.pApplicationInfo = &app_info;
500
600
info.enabledExtensionCount = g_state.enabled_instance_extensions .size ();
501
601
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 ();
514
604
515
605
if (d.vkCreateInstance (&info, nullptr , &g_state.instance ) != VK_SUCCESS) {
516
606
std::cerr << " Failed to create Vulkan instance." << std::endl;
@@ -798,8 +888,24 @@ int main(int argc, char** argv) {
798
888
nullptr );
799
889
d.vkDestroyFence (g_state.device , g_state.image_ready_fence , nullptr );
800
890
891
+ if (g_state.swapchain ) {
892
+ d.vkDestroySwapchainKHR (g_state.device , g_state.swapchain , nullptr );
893
+ }
894
+
801
895
d.vkDestroyDevice (g_state.device , nullptr );
802
896
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
+
803
909
d.vkDestroyInstance (g_state.instance , nullptr );
804
910
805
911
glfwDestroyWindow (g_state.window );
0 commit comments