Skip to content

Commit 8c72d2c

Browse files
vkconfig: Add environment variables export of loader config
1 parent 534177f commit 8c72d2c

5 files changed

Lines changed: 225 additions & 0 deletions

File tree

vkconfig_core/configurator.cpp

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
280443
bool Configurator::WriteLayersSettings(OverrideArea override_area, const Path& layers_settings_path) {
281444
if (override_area & OVERRIDE_AREA_LAYERS_SETTINGS_BIT) {

vkconfig_core/configurator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class Configurator {
9999

100100
bool WriteLayersSettings(OverrideArea override_area, const Path& layers_settings_path);
101101
bool WriteLoaderSettings(OverrideArea override_area, const Path& loader_settings_path);
102+
bool Export(const Path& export_path) const;
102103

103104
void Set(HideMessageType type);
104105
bool Get(HideMessageType type) const;

vkconfig_gui/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
### Features:
55
- Add support for layer-defined messages
66
- Add support for external `vk_layer_settings.txt` files
7+
- Add environment variables export of loader configurations
78

89
### Improvements:
910
- Improved layer settings documentation

vkconfig_gui/tab_configurations.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,14 @@ bool TabConfigurations::EventFilter(QObject *target, QEvent *event) {
562562
action_export_settings->setEnabled(item != nullptr);
563563
menu.addAction(action_export_settings);
564564

565+
QAction *action_export_env_variables_bash_script = new QAction("Export the Bash script...", nullptr);
566+
action_export_env_variables_bash_script->setEnabled(item != nullptr);
567+
menu.addAction(action_export_env_variables_bash_script);
568+
/* TODO
569+
QAction *action_export_env_variables_cmd_script = new QAction("Export the Command Prompt script...",
570+
nullptr); action_export_env_variables_cmd_script->setEnabled(item != nullptr);
571+
menu.addAction(action_export_env_variables_cmd_script);
572+
*/
565573
menu.addSeparator();
566574

567575
QAction *action_external_settings = new QAction("Use External Layers Settings file...", nullptr);
@@ -587,6 +595,12 @@ bool TabConfigurations::EventFilter(QObject *target, QEvent *event) {
587595
this->OnContextMenuResetAllClicked(item);
588596
} else if (action == action_export_config) {
589597
this->OnContextMenuExportConfigsClicked(item);
598+
} else if (action == action_export_env_variables_bash_script) {
599+
this->OnContextMenuExportEnvVariablesBashClicked(item);
600+
/* TODO
601+
} else if (action == action_export_env_variables_cmd_script) {
602+
this->OnContextMenuExportEnvVariablesCMDClicked(item);
603+
*/
590604
} else if (action == action_export_settings) {
591605
this->OnContextMenuExportSettingsClicked(item);
592606
} else if (action == action_external_settings) {
@@ -1016,6 +1030,50 @@ void TabConfigurations::OnContextMenuExportConfigsClicked(ListItem *item) {
10161030
}
10171031
}
10181032

1033+
void TabConfigurations::OnContextMenuExportEnvVariablesBashClicked(ListItem *item) {
1034+
assert(item);
1035+
Configurator &configurator = Configurator::Get();
1036+
1037+
const Path path_export = configurator.configurations.last_path_export_config.RelativePath() + "/" + item->key + ".sh";
1038+
const QString &selected_path = QFileDialog::getSaveFileName(&this->window, "Export Environment Variables bash script",
1039+
path_export.AbsolutePath().c_str(), "Shell Script(*.sh)");
1040+
1041+
const bool result = configurator.Export(selected_path.toStdString());
1042+
1043+
if (!result) {
1044+
QMessageBox msg;
1045+
msg.setIcon(QMessageBox::Critical);
1046+
msg.setWindowTitle("Exporting of a file failed...");
1047+
msg.setText(format("Couldn't be create '%s' file.", selected_path.toStdString().c_str()).c_str());
1048+
msg.exec();
1049+
} else {
1050+
Path path(selected_path.toStdString());
1051+
QDesktopServices::openUrl(QUrl::fromLocalFile(path.AbsoluteDir().c_str()));
1052+
}
1053+
}
1054+
1055+
void TabConfigurations::OnContextMenuExportEnvVariablesCMDClicked(ListItem *item) {
1056+
assert(item);
1057+
Configurator &configurator = Configurator::Get();
1058+
1059+
const Path path_export = configurator.configurations.last_path_export_config.RelativePath() + "/" + item->key + ".bat";
1060+
const QString &selected_path = QFileDialog::getSaveFileName(&this->window, "Export Environment Variables command prompt script",
1061+
path_export.AbsolutePath().c_str(), "Shell Script(*.sh)");
1062+
1063+
const bool result = configurator.Export(selected_path.toStdString());
1064+
1065+
if (!result) {
1066+
QMessageBox msg;
1067+
msg.setIcon(QMessageBox::Critical);
1068+
msg.setWindowTitle("Exporting of a file failed...");
1069+
msg.setText(format("Couldn't be create '%s' file.", selected_path.toStdString().c_str()).c_str());
1070+
msg.exec();
1071+
} else {
1072+
Path path(selected_path.toStdString());
1073+
QDesktopServices::openUrl(QUrl::fromLocalFile(path.AbsoluteDir().c_str()));
1074+
}
1075+
}
1076+
10191077
void TabConfigurations::OnContextMenuExportSettingsClicked(ListItem *item) {
10201078
assert(item);
10211079

vkconfig_gui/tab_configurations.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class TabConfigurations : public Tab {
9393
void OnContextMenuResetOneClicked(ListItem *item);
9494
void OnContextMenuResetAllClicked(ListItem *item);
9595
void OnContextMenuExportConfigsClicked(ListItem *item);
96+
void OnContextMenuExportEnvVariablesBashClicked(ListItem *item);
97+
void OnContextMenuExportEnvVariablesCMDClicked(ListItem *item);
9698
void OnContextMenuExportSettingsClicked(ListItem *item);
9799

98100
void UpdatePerExecutableConfigurations();

0 commit comments

Comments
 (0)