@@ -276,6 +276,169 @@ bool Configurator::WriteLoaderSettings(OverrideArea override_area, const Path& l
276276 }
277277}
278278
279+ bool Configurator::Export (const Path& export_path) const {
280+ QFile file (export_path.AbsolutePath ().c_str ());
281+
282+ const bool result_layers_file = file.open (QIODevice::WriteOnly | QIODevice::Text);
283+ if (!result_layers_file) {
284+ return false ;
285+ }
286+
287+ bool has_missing_layers = false ;
288+ const Configuration* configuration = this ->GetActiveConfiguration ();
289+
290+ QTextStream stream (&file);
291+
292+ stream << " #! Loader Settings:\n " ;
293+
294+ const std::vector<std::string>& stderr_log = GetLogTokens (configuration->loader_log_messages_flags );
295+ const std::string stderr_logs = Merge (stderr_log, " ," );
296+
297+ if (configuration->override_loader ) {
298+ stream << " export VK_LOADER_DEBUG=" << stderr_logs.c_str () << " \n " ;
299+ }
300+ if (configuration->override_layers ) {
301+ stream << " #! For now, the Vulkan Loader doesn't fully support the same behavior with environment variables than what's "
302+ " supported with Vulkan Configurator...\n " ;
303+ stream << " #! The Vulkan Loader doesn't support fully ordering layers with environment variables.\n " ;
304+ stream << " export VK_LOADER_LAYERS_ENABLE=" ;
305+
306+ std::vector<std::string> layer_list;
307+ for (std::size_t i = 0 , n = configuration->parameters .size (); i < n; ++i) {
308+ const Parameter& parameter = configuration->parameters [i];
309+ if (parameter.control != LAYER_CONTROL_ON ) {
310+ continue ;
311+ }
312+ layer_list.push_back (parameter.key );
313+ }
314+ stream << Merge (layer_list, " ," ).c_str ();
315+ stream << " \n " ;
316+ }
317+
318+ stream << " \n " ;
319+
320+ stream << " #! Layers Settings:\n " ;
321+
322+ // Loop through all the layers
323+ for (std::size_t j = 0 , n = configuration->parameters .size (); j < n; ++j) {
324+ const Parameter& parameter = configuration->parameters [j];
325+ if (!parameter.override_settings ) {
326+ continue ;
327+ }
328+
329+ if (!(parameter.platform_flags & (1 << VKC_PLATFORM ))) {
330+ continue ;
331+ }
332+
333+ if (parameter.builtin == LAYER_BUILTIN_UNORDERED ) {
334+ continue ;
335+ }
336+
337+ if (parameter.control == LAYER_CONTROL_DISCARD || parameter.control == LAYER_CONTROL_OFF ) {
338+ continue ;
339+ }
340+
341+ const Layer* layer = this ->layers .Find (parameter.key .c_str (), parameter.api_version );
342+ if (layer == nullptr ) {
343+ if (parameter.control == LAYER_CONTROL_ON ) {
344+ has_missing_layers = true ;
345+ fprintf (stderr,
346+ " vkconfig: [ERROR] `%s` layer is set to `%s` in `%s` loader configuration but missing and being "
347+ " ignored\n " ,
348+ parameter.key .c_str (), ::GetLabel (parameter.control ), configuration->key .c_str ());
349+ } else {
350+ fprintf (stderr,
351+ " vkconfig: [WARNING] `%s` layer is set to `%s` in `%s` loader configuration but missing and being "
352+ " ignored\n " ,
353+ parameter.key .c_str (), ::GetLabel (parameter.control ), configuration->key .c_str ());
354+ }
355+ continue ;
356+ }
357+
358+ stream << " \n " ;
359+ stream << " #! " << layer->key .c_str () << " " << layer->api_version .str ().c_str () << " \n\n " ;
360+
361+ std::string lc_layer_name = GetLayerSettingPrefix (layer->key );
362+
363+ for (std::size_t i = 0 , m = parameter.settings .size (); i < m; ++i) {
364+ const SettingData* setting_data = parameter.settings [i];
365+
366+ // Skip groups - they aren't settings, so not relevant in this output
367+ if (setting_data->type == SETTING_GROUP ) {
368+ continue ;
369+ }
370+
371+ // Skip missing settings
372+ const SettingMeta* meta = FindSetting (layer->settings , setting_data->key .c_str ());
373+ if (meta == nullptr ) {
374+ continue ;
375+ }
376+
377+ // Skip overriden settings
378+ if (::CheckSettingOverridden (*meta)) {
379+ continue ;
380+ }
381+
382+ stream << " #! " ;
383+ stream << meta->label .c_str ();
384+ stream << " \n #! =====================\n " ;
385+ stream << " #! " << meta->key .c_str ();
386+
387+ if (meta->status != STATUS_STABLE ) {
388+ stream << format (" (%s)" , GetToken (meta->status )).c_str ();
389+ }
390+
391+ stream << " \n " ;
392+
393+ // Break up description into smaller words
394+ std::string description = meta->description ;
395+ std::vector<std::string> words;
396+ std::size_t pos;
397+ while ((pos = description.find (" " )) != std::string::npos) {
398+ words.push_back (description.substr (0 , pos));
399+ description.erase (0 , pos + 1 );
400+ }
401+ if (description.size () > 0 ) words.push_back (description);
402+ if (words.size () > 0 ) {
403+ stream << " #!" ;
404+ std::size_t nchars = 2 ;
405+ for (auto word : words) {
406+ if (word.size () + nchars > 80 ) {
407+ stream << " \n #!" ;
408+ nchars = 3 ;
409+ }
410+ stream << " " << word.c_str ();
411+ nchars += (word.size () + 1 );
412+ }
413+ }
414+ stream << " \n " ;
415+
416+ // If feature has unmet dependency, output it but comment it out
417+ if (::CheckDependence (*meta, parameter.settings ) != SETTING_DEPENDENCE_ENABLE ) {
418+ stream << " #!" ;
419+ }
420+
421+ if (meta->status == STATUS_DEPRECATED && !meta->deprecated_by_key .empty ()) {
422+ const SettingMeta* replaced_setting = FindSetting (layer->settings , meta->deprecated_by_key .c_str ());
423+
424+ stream << format (" #! This setting was deprecated and replaced by '%s' (%s) setting.\n " ,
425+ replaced_setting->label .c_str (), replaced_setting->key .c_str ())
426+ .c_str ();
427+ }
428+
429+ std::vector<std::string> data = ::BuildEnvVariablesList (layer->key .c_str (), setting_data->key .c_str (), false );
430+
431+ stream << " export " << data[0 ].c_str () << " =" ;
432+ stream << setting_data->Export (EXPORT_MODE_OVERRIDE ).c_str ();
433+ stream << " \n\n " ;
434+ }
435+ }
436+
437+ file.close ();
438+
439+ return true ;
440+ }
441+
279442// Create and write vk_layer_settings.txt file
280443bool Configurator::WriteLayersSettings (OverrideArea override_area, const Path& layers_settings_path) {
281444 if (override_area & OVERRIDE_AREA_LAYERS_SETTINGS_BIT ) {
0 commit comments