@@ -33,6 +33,79 @@ static const char *find_extensions(const VkExtensionProperties *avail,
33
33
return NULL ;
34
34
}
35
35
36
+ static char * * get_validation_layers (uint32_t * layer_count ) {
37
+ // TODO request layer via env var
38
+ static const char * layers [] = {
39
+ "VK_LAYER_KHRONOS_validation" ,
40
+ // "VK_LAYER_RENDERDOC_Capture",
41
+ // "VK_LAYER_live_introspection",
42
+ };
43
+
44
+ static const size_t layers_len = sizeof (layers ) / sizeof (layers [0 ]);
45
+
46
+ uint32_t count ;
47
+ vkEnumerateInstanceLayerProperties (& count , NULL );
48
+
49
+ if (count == 0 ) {
50
+ wlr_log (WLR_DEBUG , "No validation layers found" );
51
+ goto layers_err ;
52
+ }
53
+ wlr_log (WLR_DEBUG , "Found %" PRIu32 " validation layers" , count );
54
+
55
+ VkLayerProperties * layer_props = calloc ((size_t )count ,
56
+ sizeof (VkLayerProperties ));
57
+ if (layer_props == NULL ) {
58
+ wlr_log (WLR_ERROR , "Failed to allocate %" PRIu32 " VkLayerProperties" ,
59
+ count );
60
+ goto layers_err ;
61
+ }
62
+
63
+ uint32_t found_layers_count = 0 ;
64
+ char * * found_layers = calloc ((size_t )count , sizeof (char * ));
65
+ if (found_layers == NULL ) {
66
+ wlr_log (WLR_ERROR , "Failed to allocate validation layers" );
67
+ goto layers_err ;
68
+ }
69
+
70
+ vkEnumerateInstanceLayerProperties (& count , layer_props );
71
+ for (size_t i = 0 ; i < (size_t )count ; ++ i ) {
72
+ wlr_log (WLR_DEBUG , "Vulkan instance validation layer %s v%" PRIu32 ,
73
+ layer_props [i ].layerName , layer_props [i ].implementationVersion );
74
+ for (size_t j = 0 ; j < layers_len ; ++ j ) {
75
+ if (strcmp (layer_props [i ].layerName , layers [j ]) == 0 ) {
76
+ found_layers [found_layers_count ] = calloc (
77
+ VK_MAX_EXTENSION_NAME_SIZE , sizeof (char ));
78
+ if (found_layers [found_layers_count ] == NULL ) {
79
+ wlr_log (WLR_ERROR , "Failed to allocate validation layer" );
80
+ goto layers_err ;
81
+ }
82
+
83
+ strcpy (found_layers [found_layers_count ], layers [j ]);
84
+ found_layers_count ++ ;
85
+ break ;
86
+ }
87
+ }
88
+ }
89
+
90
+ free (layer_props );
91
+
92
+ * layer_count = found_layers_count ;
93
+ return found_layers ;
94
+
95
+ layers_err :
96
+ free (layer_props );
97
+
98
+ if (found_layers ) {
99
+ for (uint32_t i = 0 ; i < found_layers_count ; ++ i ) {
100
+ free (found_layers [i ]);
101
+ }
102
+ }
103
+
104
+ free (found_layers );
105
+ * layer_count = 0 ;
106
+ return NULL ;
107
+ }
108
+
36
109
static VkBool32 debug_callback (VkDebugUtilsMessageSeverityFlagBitsEXT severity ,
37
110
VkDebugUtilsMessageTypeFlagsEXT type ,
38
111
const VkDebugUtilsMessengerCallbackDataEXT * debug_data ,
@@ -163,21 +236,21 @@ struct wlr_vk_instance *vulkan_instance_create(size_t ext_count,
163
236
application_info .engineVersion = WLR_VERSION_NUM ;
164
237
application_info .apiVersion = VK_API_VERSION_1_1 ;
165
238
166
- const char * layers [] = {
167
- "VK_LAYER_KHRONOS_validation" ,
168
- // "VK_LAYER_RENDERDOC_Capture ",
169
- // "VK_LAYER_live_introspection",
170
- };
171
-
172
- unsigned layer_count = debug * ( sizeof ( layers ) / sizeof ( layers [ 0 ]));
239
+ uint32_t layer_count = 0 ;
240
+ char * * layers = get_validation_layers ( & layer_count );
241
+ wlr_log ( WLR_DEBUG , "Using %" PRIu32 " instance validation layers " ,
242
+ layer_count );
243
+ for ( uint32_t i = 0 ; i < layer_count ; ++ i ) {
244
+ wlr_log ( WLR_DEBUG , "%s" , layers [ i ]);
245
+ }
173
246
174
247
VkInstanceCreateInfo instance_info = {0 };
175
248
instance_info .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO ;
176
249
instance_info .pApplicationInfo = & application_info ;
177
250
instance_info .enabledExtensionCount = ini -> extension_count ;
178
251
instance_info .ppEnabledExtensionNames = ini -> extensions ;
179
252
instance_info .enabledLayerCount = layer_count ;
180
- instance_info .ppEnabledLayerNames = layers ;
253
+ instance_info .ppEnabledLayerNames = ( const char * const * ) layers ;
181
254
182
255
VkDebugUtilsMessageSeverityFlagsEXT severity =
183
256
// VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
@@ -204,6 +277,12 @@ struct wlr_vk_instance *vulkan_instance_create(size_t ext_count,
204
277
}
205
278
206
279
res = vkCreateInstance (& instance_info , NULL , & ini -> instance );
280
+
281
+ for (size_t i = 0 ; i < layer_count ; ++ i ) {
282
+ free (layers [i ]);
283
+ }
284
+ free (layers );
285
+
207
286
if (res != VK_SUCCESS ) {
208
287
wlr_vk_error ("Could not create instance" , res );
209
288
goto error ;
0 commit comments