diff --git a/vkconfig/dialog_applications.cpp b/vkconfig/dialog_applications.cpp index 6313c1d51f..07053cc16e 100644 --- a/vkconfig/dialog_applications.cpp +++ b/vkconfig/dialog_applications.cpp @@ -149,7 +149,7 @@ QTreeWidgetItem *ApplicationsDialog::CreateApplicationItem(const Application &ap if (configurator.environment.GetUseApplicationList()) { QCheckBox *check_box = new QCheckBox(application.app_name.c_str()); - check_box->setChecked(application.override_layers); + check_box->setChecked(application.layers_mode != LAYERS_MODE_BY_APPLICATIONS); ui->treeWidget->setItemWidget(item, 0, check_box); connect(check_box, SIGNAL(stateChanged(int)), this, SLOT(OnStateChanged(int))); } else { @@ -233,7 +233,8 @@ void ApplicationsDialog::itemChanged(QTreeWidgetItem *item, int column) { _last_selected_application_index = ui->treeWidget->indexOfTopLevelItem(item); QCheckBox *check_box = dynamic_cast(ui->treeWidget->itemWidget(item, column)); if (check_box != nullptr) { - Configurator::Get().environment.GetApplication(_last_selected_application_index).override_layers = check_box->isChecked(); + Configurator::Get().environment.GetApplication(_last_selected_application_index).layers_mode = + check_box->isChecked() ? LAYERS_MODE_BY_CONFIGURATOR_RUNNING : LAYERS_MODE_BY_APPLICATIONS; } } @@ -252,7 +253,8 @@ void ApplicationsDialog::OnStateChanged(int) { QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i); QCheckBox *check_box = dynamic_cast(ui->treeWidget->itemWidget(item, 0)); assert(check_box != nullptr); - environment.GetApplication(i).override_layers = check_box->isChecked(); + environment.GetApplication(i).layers_mode = + check_box->isChecked() ? LAYERS_MODE_BY_CONFIGURATOR_RUNNING : LAYERS_MODE_BY_APPLICATIONS; } } diff --git a/vkconfig3/CMakeLists.txt b/vkconfig3/CMakeLists.txt index 1c74525600..6ccefe12d8 100644 --- a/vkconfig3/CMakeLists.txt +++ b/vkconfig3/CMakeLists.txt @@ -28,19 +28,19 @@ else() endif() if(WIN32) - add_executable(vkconfig3 WIN32 ${FILES_ALL} ${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/vkconfig.rc) - target_compile_definitions(vkconfig3 PRIVATE _CRT_SECURE_NO_WARNINGS) - target_compile_options(vkconfig3 PRIVATE $<$:/MP>) - target_link_libraries(vkconfig3 Cfgmgr32) + add_executable(vkconfig-gui WIN32 ${FILES_ALL} ${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/vkconfig.rc) + target_compile_definitions(vkconfig-gui PRIVATE _CRT_SECURE_NO_WARNINGS) + target_compile_options(vkconfig-gui PRIVATE $<$:/MP>) + target_link_libraries(vkconfig-gui Cfgmgr32) else() - add_executable(vkconfig3 ${FILES_ALL} ${FILES_UI}) + add_executable(vkconfig-gui ${FILES_ALL} ${FILES_UI}) endif() - target_link_libraries(vkconfig3 Vulkan::Headers vkconfig_core Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Network) - target_compile_definitions(vkconfig3 PRIVATE QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT) - set_target_properties(vkconfig3 PROPERTIES FOLDER "vkconfig") + target_link_libraries(vkconfig-gui Vulkan::Headers vkconfig_core Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Network) + target_compile_definitions(vkconfig-gui PRIVATE QT_NO_DEBUG_OUTPUT QT_NO_WARNING_OUTPUT) + set_target_properties(vkconfig-gui PROPERTIES FOLDER "vkconfig") - install(TARGETS vkconfig3 DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(TARGETS vkconfig-gui DESTINATION ${CMAKE_INSTALL_BINDIR}) if(WIN32) get_target_property(QMAKE_EXE Qt5::qmake IMPORTED_LOCATION) diff --git a/vkconfig3/configurator.cpp b/vkconfig3/configurator.cpp index 74d391a680..c1fee594e9 100644 --- a/vkconfig3/configurator.cpp +++ b/vkconfig3/configurator.cpp @@ -175,7 +175,7 @@ void Configurator::UpdateDevices() { pfnDestroyInstance(instance, NULL); } -bool Configurator::SupportDifferentLayerVersions(Version *return_loader_version) const { +bool Configurator::SupportLoaderSettings(Version *return_loader_version) const { // Check loader version const Version version = GetVulkanLoaderVersion(); assert(version != Version::VERSION_NULL); @@ -184,19 +184,7 @@ bool Configurator::SupportDifferentLayerVersions(Version *return_loader_version) *return_loader_version = version; } - return version >= Version("1.3.212"); -} - -bool Configurator::SupportApplicationList(Version *return_loader_version) const { - // Check loader version - const Version version = GetVulkanLoaderVersion(); - assert(version != Version::VERSION_NULL); - - if (return_loader_version) { - *return_loader_version = version; - } - - return version >= Version("1.2.141"); + return version >= Version("1.3.261"); } void Configurator::ResetToDefault(bool hard) { diff --git a/vkconfig3/configurator.h b/vkconfig3/configurator.h index 8d3d433777..6cdc5a62d6 100644 --- a/vkconfig3/configurator.h +++ b/vkconfig3/configurator.h @@ -29,7 +29,7 @@ #include "../vkconfig_core/configuration_manager.h" #include "../vkconfig_core/platform.h" -static const std::vector SUPPORTED_CONFIG_FILES = {"_2_2_3", "_2_2_2", "_2_2_1"}; +static const std::vector SUPPORTED_CONFIG_FILES = {"_2_2_3"}; class Configurator { public: @@ -38,22 +38,12 @@ class Configurator { // The list of applications affected public: - bool SupportDifferentLayerVersions(Version* return_loader_version = nullptr) const; - - // If return_loader_version is not null, the function will return the loader version - // If quiet is false, message box will be generate - bool SupportApplicationList(Version* return_loader_version = nullptr) const; - - bool HasActiveOverrideOnApplicationListOnly() const { - return SupportApplicationList() && environment.HasOverriddenApplications(); - } + bool SupportLoaderSettings(Version* return_loader_version = nullptr) const; void ActivateConfiguration(const std::string& configuration_name); void ResetToDefault(bool hard); - std::string profile_file; - std::vector GetDeviceNames() const; private: @@ -63,7 +53,6 @@ class Configurator { Configurator(const Configurator&) = delete; Configurator& operator=(const Configurator&) = delete; - void CopyResourceFiles(); void UpdateDevices(); public: diff --git a/vkconfig3/dialog_applications.cpp b/vkconfig3/dialog_applications.cpp index b117e26642..7217f61939 100644 --- a/vkconfig3/dialog_applications.cpp +++ b/vkconfig3/dialog_applications.cpp @@ -149,7 +149,7 @@ QTreeWidgetItem *ApplicationsDialog::CreateApplicationItem(const Application &ap if (configurator.environment.GetUseApplicationList()) { QCheckBox *check_box = new QCheckBox(application.app_name.c_str()); - check_box->setChecked(application.override_layers); + check_box->setChecked(application.layers_mode != LAYERS_MODE_BY_APPLICATIONS); ui->treeWidget->setItemWidget(item, 0, check_box); connect(check_box, SIGNAL(clicked(bool)), this, SLOT(itemClicked(bool))); } else { @@ -233,7 +233,8 @@ void ApplicationsDialog::itemChanged(QTreeWidgetItem *item, int column) { _last_selected_application_index = ui->treeWidget->indexOfTopLevelItem(item); QCheckBox *check_box = dynamic_cast(ui->treeWidget->itemWidget(item, column)); if (check_box != nullptr) { - Configurator::Get().environment.GetApplication(_last_selected_application_index).override_layers = check_box->isChecked(); + Configurator::Get().environment.GetApplication(_last_selected_application_index).layers_mode = + check_box->isChecked() ? LAYERS_MODE_BY_CONFIGURATOR_RUNNING : LAYERS_MODE_BY_APPLICATIONS; } } @@ -254,7 +255,8 @@ void ApplicationsDialog::itemClicked(bool clicked) { QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i); QCheckBox *check_box = dynamic_cast(ui->treeWidget->itemWidget(item, 0)); assert(check_box != nullptr); - environment.GetApplication(i).override_layers = check_box->isChecked(); + environment.GetApplication(i).layers_mode = + check_box->isChecked() ? LAYERS_MODE_BY_CONFIGURATOR_RUNNING : LAYERS_MODE_BY_APPLICATIONS; } } diff --git a/vkconfig3/mainwindow.cpp b/vkconfig3/mainwindow.cpp index fecb1c0f2f..12dbfeae89 100644 --- a/vkconfig3/mainwindow.cpp +++ b/vkconfig3/mainwindow.cpp @@ -184,8 +184,6 @@ MainWindow::MainWindow(QWidget *parent) connect(ui->configurations_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(OnConfigurationTreeClicked(QTreeWidgetItem *, int))); - connect(ui->combo_box_mode, SIGNAL(currentIndexChanged(int)), this, SLOT(OnComboBoxModeChanged(int))); - connect(ui->settings_tree, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(editorExpanded(QTreeWidgetItem *))); connect(ui->settings_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(OnSettingsTreeClicked(QTreeWidgetItem *, int))); @@ -215,6 +213,9 @@ MainWindow::MainWindow(QWidget *parent) ui->edit_env->setText(application.env.c_str()); ui->edit_log->setText(ReplaceBuiltInVariable(application.log_file.c_str()).c_str()); + ui->execute_closer_application_label->setVisible(true); + ui->execute_closer_driver_label->setVisible(true); + // ui->check_box_persistent->setToolTip("Keep Vulkan Configurator running in system tray when closing the main window"); // ui->check_box_persistent->setVisible(QSystemTrayIcon::isSystemTrayAvailable()); @@ -227,6 +228,8 @@ MainWindow::MainWindow(QWidget *parent) ui->log_browser->document()->setMaximumBlockCount(2048); // ui->configuration_tree->scrollToItem(ui->configuration_tree->topLevelItem(0), QAbstractItemView::PositionAtTop); + ui->check_box_per_application->setChecked(configurator.environment.GetPerApplicationConfig()); + this->InitTray(); this->UpdateTray(); this->UpdateUI(); @@ -437,7 +440,9 @@ void MainWindow::AddLayerItem(const Parameter ¶meter) { // We simply hide these layers to avoid confusing the Vulkan developers if (parameter.state == LAYER_STATE_EXCLUDED) return; - decorated_name += " (Missing)"; + if (parameter.control != LAYER_STATE_APPLICATION_CONTROLLED && parameter.control != LAYER_CONTROL_UNORDERED) { + decorated_name += " (Missing)"; + } } TreeWidgetItemParameter *item_state = new TreeWidgetItemParameter(parameter.key.c_str()); @@ -507,25 +512,16 @@ void MainWindow::UpdateUI() { this->blockSignals(true); ui->configurations_tree->blockSignals(true); - ui->combo_box_mode->blockSignals(true); - ui->combo_box_mode->setCurrentIndex(environment.GetMode()); - ui->combo_box_mode->blockSignals(false); - // Add applications - ui->combo_box_applications->blockSignals(true); ui->combo_box_applications->setEnabled(ui->check_box_per_application->isChecked()); const std::vector &applications = environment.GetApplications(); for (std::size_t i = 0, n = applications.size(); i < n; ++i) { - ui->combo_box_applications->addItem(applications[i].app_name.c_str()); + ui->combo_box_applications->addItem(ReplaceBuiltInVariable(applications[i].executable_path.c_str()).c_str()); } ui->combo_box_applications->setCurrentIndex(environment.GetActiveApplicationIndex()); - ui->combo_box_applications->blockSignals(false); const bool has_active_configuration = configurator.configurations.HasActiveConfiguration(configurator.layers.selected_layers); - const bool enable_layer_ui = - (ui->combo_box_mode->currentIndex() == LAYERS_MODE_BY_CONFIGURATOR_RUNNING) && has_selected_configuration; - // Mode states this->UpdateTray(); // ui->tree_layers_paths->blockSignals(true); @@ -575,7 +571,6 @@ void MainWindow::UpdateUI() { */ // Update configurations - ui->group_box_configurations->setEnabled(environment.GetMode() == LAYERS_MODE_BY_CONFIGURATOR_RUNNING); ui->configurations_tree->setCurrentItem(nullptr); for (int i = 0, n = ui->configurations_tree->topLevelItemCount(); i < n; ++i) { @@ -608,7 +603,7 @@ void MainWindow::UpdateUI() { // Load Layers paths std::vector layer_paths = configurator.layers.BuildPathList(); - ui->tree_layers_paths->setEnabled(enable_layer_ui); + // ui->tree_layers_paths->setEnabled(enable_layer_ui); ui->tree_layers_paths->clear(); for (std::size_t path_index = 0, count = layer_paths.size(); path_index < count; ++path_index) { @@ -620,7 +615,7 @@ void MainWindow::UpdateUI() { ui->tree_layers_paths->update(); // Load Layers items - ui->layers_tree->setEnabled(enable_layer_ui); + // ui->layers_tree->setEnabled(enable_layer_ui); ui->layers_tree->clear(); if (has_selected_configuration) { @@ -628,35 +623,37 @@ void MainWindow::UpdateUI() { FindByKey(configurator.configurations.available_configurations, selected_contiguration_name.c_str()); if (configuration != nullptr) { std::vector parameters = GatherParameters(configuration->parameters, configurator.layers.selected_layers); - + /* { QListWidgetItem *item = new QListWidgetItem(); ui->layers_tree->addItem(item); item->setText(TEXT_EXECUTE_CLOSER_APPLICATION); - item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + //item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + item->setFlags(0); item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); QFont font = item->font(); font.setItalic(true); item->setFont(font); // item->setDisabled(true); } - + */ for (std::size_t i = 0, n = parameters.size(); i < n; ++i) { AddLayerItem(parameters[i]); } - + /* { QListWidgetItem *item = new QListWidgetItem(); ui->layers_tree->addItem(item); item->setText(TEXT_EXECUTE_CLOSER_DRIVER); - item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + //item->setFlags(item->flags() & ~Qt::ItemIsSelectable); + item->setFlags(0); item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); QFont font = item->font(); font.setItalic(true); item->setFont(font); // item->setDisabled(true); } - + */ resizeEvent(nullptr); ui->layers_tree->update(); @@ -907,17 +904,44 @@ void MainWindow::on_check_box_apply_list_clicked() { } */ -void MainWindow::OnComboBoxModeChanged(int index) { +void MainWindow::on_combo_box_mode_currentIndexChanged(int index) { Configurator &configurator = Configurator::Get(); - configurator.environment.SetMode(static_cast(ui->combo_box_mode->currentIndex())); - configurator.ActivateConfiguration(configurator.environment.GetSelectedConfiguration()); - UpdateUI(); + + if (configurator.environment.GetPerApplicationConfig()) { + Application &application = configurator.environment.GetApplication(configurator.environment.GetActiveApplicationIndex()); + application.layers_mode = static_cast(index); + } else { + configurator.environment.SetMode(static_cast(index)); + configurator.ActivateConfiguration(configurator.environment.GetSelectedConfiguration()); + } + + const bool enabled_ui = index == LAYERS_MODE_BY_CONFIGURATOR_RUNNING; + + ui->group_box_configurations->setEnabled(enabled_ui); + ui->group_box_settings->setEnabled(enabled_ui); + ui->group_box_layers->setEnabled(enabled_ui); } -void MainWindow::on_check_box_per_application_clicked() { - ui->combo_box_applications->setEnabled(ui->check_box_per_application->isChecked()); +void MainWindow::on_combo_box_applications_currentIndexChanged(int index) { + Configurator &configurator = Configurator::Get(); + configurator.environment.SelectActiveApplication(index); - Configurator::Get().environment.SetPerApplicationConfig(ui->check_box_per_application->isChecked()); + Application &application = configurator.environment.GetApplication(configurator.environment.GetActiveApplicationIndex()); + ui->combo_box_applications->setToolTip(ReplaceBuiltInVariable(application.executable_path.c_str()).c_str()); + ui->combo_box_mode->setCurrentIndex(application.layers_mode); +} + +void MainWindow::on_check_box_per_application_toggled(bool checked) { + Configurator &configurator = Configurator::Get(); + configurator.environment.SetPerApplicationConfig(checked); + + ui->combo_box_applications->setEnabled(configurator.environment.GetPerApplicationConfig()); + if (checked) { + Application &application = configurator.environment.GetApplication(configurator.environment.GetActiveApplicationIndex()); + ui->combo_box_mode->setCurrentIndex(application.layers_mode); + } else { + ui->combo_box_mode->setCurrentIndex(configurator.environment.GetMode()); + } } void MainWindow::on_check_box_clear_on_launch_clicked() { @@ -943,14 +967,16 @@ void MainWindow::OnConfigurationItemClicked(bool checked) { // Someone just got checked, they are now the current profile // This pointer will only be valid if it's one of the elements with // the radio button - ConfigurationListItem *item = GetCheckedItem(); - if (item == nullptr) return; + ConfigurationListItem *configuration_item = GetCheckedItem(); + if (configuration_item == nullptr) { + return; + } // This appears redundant on Windows, but under linux it is needed // to ensure the new item is "selected" // ui->tree_configurations->setCurrentItem(item); - Configurator::Get().ActivateConfiguration(item->configuration_name); + Configurator::Get().ActivateConfiguration(configuration_item->configuration_name); UpdateUI(); } @@ -1181,7 +1207,7 @@ void MainWindow::resizeEvent(QResizeEvent *event) { if (event != nullptr) event->accept(); const QFontMetrics fm = ui->layers_tree->fontMetrics(); - const int combo_width = (fm.size(Qt::TextSingleLine, "Application-Controlled").width() * 1.6); + const int combo_width = (fm.size(Qt::TextSingleLine, "Auto").width() * 1.6); const int width = ui->layers_tree->width() - combo_width; // ui->tree_layers_list->setColumnWidth(0, width); @@ -1726,16 +1752,11 @@ bool MainWindow::eventFilter(QObject *target, QEvent *event) { if (right_click) { QListWidgetItem *item = ui->layers_tree->itemAt(right_click->pos()); - const std::string text = item->text().toStdString(); - if (text == TEXT_EXECUTE_CLOSER_APPLICATION) { - return false; - } - if (text == TEXT_EXECUTE_CLOSER_DRIVER) { + const Layer *layer = GetLayer(ui->layers_tree, item); + if (layer == nullptr) { return false; } - const Layer *layer = GetLayer(ui->layers_tree, item); - QMenu menu(ui->layers_tree); QFont subtitle_font = menu.font(); subtitle_font.setBold(true); diff --git a/vkconfig3/mainwindow.h b/vkconfig3/mainwindow.h index b505de8d21..0d68b6355b 100644 --- a/vkconfig3/mainwindow.h +++ b/vkconfig3/mainwindow.h @@ -63,28 +63,34 @@ class LayerWidget : public QLabel { : item(item), layer_version(nullptr), layer_state(nullptr) { const bool is_implicit_layer = layers.empty() ? false : layers[0]->type == LAYER_TYPE_IMPLICIT; - this->layer_version = new QComboBox(this); - this->layer_version->addItem(layers.empty() ? "0.0.000" : layers[0]->api_version.str().c_str()); - this->layer_version->setToolTip(layers[0]->manifest_path.c_str()); - // this->layer_version->setEnabled(layers.size() > 1); - this->layer_version->installEventFilter(this); - - this->layer_state = new QComboBox(this); - this->layer_state->addItem(is_implicit_layer ? "Implicitly On" : "Application-Controlled"); - this->layer_state->addItem("Forced On"); - this->layer_state->addItem("Forced Off"); - this->layer_state->setEnabled(!layers.empty()); - this->layer_state->setCurrentIndex(parameter.state); - this->layer_state->installEventFilter(this); - - std::string decorated_name(!layers.empty() ? parameter.key : layers[0]->key); + if (parameter.control != LAYER_CONTROL_APPLICATIONS && parameter.control != LAYER_CONTROL_UNORDERED) { + this->layer_version = new QComboBox(this); + this->layer_version->addItem(layers.empty() ? "0.0.000" : layers[0]->api_version.str().c_str()); + if (!layers.empty()) { + this->layer_version->setToolTip(layers[0]->manifest_path.c_str()); + } + // this->layer_version->setEnabled(layers.size() > 1); + this->layer_version->installEventFilter(this); + + this->layer_state = new QComboBox(this); + this->layer_state->addItem("Auto"); + this->layer_state->addItem("On"); + this->layer_state->addItem("Off"); + this->layer_state->setEnabled(!layers.empty()); + this->layer_state->setCurrentIndex(parameter.state); + this->layer_state->installEventFilter(this); + } + + std::string decorated_name(layers.empty() ? parameter.key : layers[0]->key); if (layers.empty()) { // A layers configuration may have excluded layer that are misssing because they are not available on this platform // We simply hide these layers to avoid confusing the Vulkan developers if (parameter.state == LAYER_STATE_EXCLUDED) return; - decorated_name += " (Missing)"; + if (parameter.control != LAYER_CONTROL_APPLICATIONS && parameter.control != LAYER_CONTROL_UNORDERED) { + decorated_name += " (Missing)"; + } } else { if (layers[0]->status != STATUS_STABLE) { decorated_name += format(" (%s)", GetToken(layers[0]->status)); @@ -114,15 +120,17 @@ class LayerWidget : public QLabel { void resizeEvent(QResizeEvent *event) override { QSize size = event->size(); - const QFontMetrics fm = this->layer_state->fontMetrics(); - const int width_state = std::max(HorizontalAdvance(fm, "Application-Controlled 000"), 80); - const int width_version = std::max(HorizontalAdvance(fm, "1.2.199 000"), 80); + if (this->layer_state != nullptr) { + const QFontMetrics fm = this->layer_state->fontMetrics(); + const int width_state = std::max(HorizontalAdvance(fm, "Auto 000"), 80); + const int width_version = std::max(HorizontalAdvance(fm, "1.2.199 000"), 80); - const QRect state_button_rect = QRect(size.width() - width_state, 0, width_state, size.height()); - this->layer_state->setGeometry(state_button_rect); + const QRect state_button_rect = QRect(size.width() - width_state, 0, width_state, size.height()); + this->layer_state->setGeometry(state_button_rect); - const QRect version_button_rect = QRect(size.width() - width_state - width_version, 0, width_version, size.height()); - this->layer_version->setGeometry(version_button_rect); + const QRect version_button_rect = QRect(size.width() - width_state - width_version, 0, width_version, size.height()); + this->layer_version->setGeometry(version_button_rect); + } } public: @@ -280,14 +288,15 @@ class MainWindow : public QMainWindow { void on_push_button_clear_log_clicked(); // void on_check_box_apply_list_clicked(); void on_check_box_clear_on_launch_clicked(); - void on_check_box_per_application_clicked(); void on_push_button_applications_clicked(); void on_push_button_new_clicked(); void on_push_button_rename_clicked(); void on_push_button_remove_clicked(); void on_push_button_duplicate_clicked(); - void OnComboBoxModeChanged(int index); + void on_check_box_per_application_toggled(bool checked); + void on_combo_box_mode_currentIndexChanged(int index); + void on_combo_box_applications_currentIndexChanged(int index); void OnConfigurationItemExpanded(QTreeWidgetItem *item); void OnConfigurationItemClicked(bool checked); diff --git a/vkconfig3/mainwindow.ui b/vkconfig3/mainwindow.ui index 1808da8534..40a90ca474 100644 --- a/vkconfig3/mainwindow.ui +++ b/vkconfig3/mainwindow.ui @@ -72,7 +72,7 @@ QTabWidget::Rounded - 4 + 3 @@ -588,8 +588,14 @@ 0 + + 0 + + + 0 + Qt::Horizontal @@ -603,6 +609,9 @@ false + + 0 + Qt::Vertical @@ -746,6 +755,12 @@ QFrame::Sunken + + 0 + + + Qt::ScrollBarAlwaysOn + QAbstractItemView::NoEditTriggers @@ -907,11 +922,11 @@ - + 0 - 1 + 0 @@ -927,7 +942,39 @@ 0 - + + 0 + + + + + + 0 + 0 + + + + + Arial + 9 + true + + + + true + + + 0 + + + Execute Closer to the Vulkan Application + + + Qt::AlignBottom|Qt::AlignHCenter + + + + @@ -948,11 +995,14 @@ QFrame::Sunken - 1 + 0 Qt::ScrollBarAlwaysOn + + 0 + QAbstractItemView::NoEditTriggers @@ -970,6 +1020,38 @@ + + + + + 0 + 0 + + + + + Arial + 9 + true + + + + true + + + 0 + + + Execute Closer to the Vulkan Driver + + + Qt::AlignBottom|Qt::AlignHCenter + + + 0 + + + @@ -980,6 +1062,9 @@ 0 + + 0 + Qt::Vertical @@ -1045,10 +1130,10 @@ QFrame::Box - QFrame::Sunken + QFrame::Plain - 1 + 0 Qt::ScrollBarAlwaysOff @@ -1056,6 +1141,9 @@ QAbstractScrollArea::AdjustToContentsOnFirstShow + + 0 + QAbstractItemView::NoEditTriggers diff --git a/vkconfig_core/application.cpp b/vkconfig_core/application.cpp index 5115ca0d5b..1189886a21 100644 --- a/vkconfig_core/application.cpp +++ b/vkconfig_core/application.cpp @@ -32,4 +32,4 @@ Application::Application(const std::string& name, const std::string& executable_ QFileInfo(executable_full_path.c_str()).baseName() + ".txt") .toStdString() .c_str()), - override_layers(true) {} + layers_mode(LAYERS_MODE_BY_CONFIGURATOR_RUNNING) {} diff --git a/vkconfig_core/application.h b/vkconfig_core/application.h index 4d637f0f14..ce44266d8f 100644 --- a/vkconfig_core/application.h +++ b/vkconfig_core/application.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020-2021 Valve Corporation - * Copyright (c) 2020-2021 LunarG, Inc. + * Copyright (c) 2020-2024 Valve Corporation + * Copyright (c) 2020-2024 LunarG, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ #include +enum LayersMode { LAYERS_MODE_BY_APPLICATIONS = 0, LAYERS_MODE_BY_CONFIGURATOR_RUNNING, LAYERS_MODE_BY_CONFIGURATOR_ALL_DISABLED }; + struct Application { Application() {} Application(const std::string& name, const std::string& executable_full_path, const std::string& arguments); @@ -34,5 +36,6 @@ struct Application { std::string arguments; std::string env; Path log_file; - bool override_layers; + LayersMode layers_mode; + std::string layers_configuration; }; diff --git a/vkconfig_core/doc.cpp b/vkconfig_core/doc.cpp index c62998a895..1f36e15cb4 100644 --- a/vkconfig_core/doc.cpp +++ b/vkconfig_core/doc.cpp @@ -464,7 +464,7 @@ void ExportMarkdownDoc(const Layer& layer, const std::string& path) { } void ExportSettingsDoc(const std::vector& available_layers, const Configuration& configuration, const std::string& path) { - if (WriteSettingsOverride(available_layers, configuration, path)) + if (WriteLayersSettings(available_layers, configuration, path)) printf("vkconfig: settings written to %s\n", path.c_str()); else printf("vkconfig: could not write %s\n", path.c_str()); diff --git a/vkconfig_core/environment.cpp b/vkconfig_core/environment.cpp index a177e15a53..c5087a6c4d 100644 --- a/vkconfig_core/environment.cpp +++ b/vkconfig_core/environment.cpp @@ -236,7 +236,7 @@ bool Environment::Load() { // Load layout state for (std::size_t i = 0; i < LAYOUT_COUNT; ++i) { - layout_states[i] = settings.value(GetLayoutStateToken(static_cast(i))).toByteArray(); + this->layout_states[i] = settings.value(GetLayoutStateToken(static_cast(i))).toByteArray(); } // Load default configuration already init @@ -296,7 +296,8 @@ bool Environment::LoadApplications() { application.app_name = app_object.value("app_name").toString().toStdString(); application.executable_path = app_object.value("app_path").toString().toStdString(); application.working_folder = app_object.value("app_folder").toString().toStdString(); - application.override_layers = !app_object.value("exclude_override").toBool(); + application.layers_mode = app_object.value("exclude_override").toBool() ? LAYERS_MODE_BY_APPLICATIONS + : LAYERS_MODE_BY_CONFIGURATOR_RUNNING; application.log_file = app_object.value("log_file").toString().toStdString(); if (application.app_name.length() == 0) { std::string path = application.executable_path.c_str(); @@ -370,7 +371,7 @@ bool Environment::SaveApplications() const { application_object.insert("app_name", applications[i].app_name.c_str()); application_object.insert("app_path", applications[i].executable_path.c_str()); application_object.insert("app_folder", applications[i].working_folder.c_str()); - application_object.insert("exclude_override", !applications[i].override_layers); + application_object.insert("exclude_override", applications[i].layers_mode == LAYERS_MODE_BY_APPLICATIONS); application_object.insert("log_file", applications[i].log_file.c_str()); // Ground work for mulitiple sets of command line arguments @@ -395,14 +396,14 @@ bool Environment::SaveApplications() const { } void Environment::SelectActiveApplication(std::size_t application_index) { - assert(application_index < applications.size()); + assert(application_index < this->applications.size()); - this->SetActiveApplication(applications[application_index].app_name); + this->SetActiveApplication(this->applications[application_index].app_name); } int Environment::GetActiveApplicationIndex() const { - for (std::size_t i = 0, n = applications.size(); i < n; ++i) { - if (applications[i].app_name == this->active_application) { + for (std::size_t i = 0, n = this->applications.size(); i < n; ++i) { + if (this->applications[i].app_name == this->active_application) { return static_cast(i); } } @@ -411,61 +412,63 @@ int Environment::GetActiveApplicationIndex() const { } bool Environment::HasOverriddenApplications() const { - for (std::size_t i = 0, n = applications.size(); i < n; ++i) { - if (applications[i].override_layers) return true; + for (std::size_t i = 0, n = this->applications.size(); i < n; ++i) { + if (this->applications[i].layers_mode != LAYERS_MODE_BY_APPLICATIONS) { + return true; + } } return false; } bool Environment::AppendApplication(const Application& application) { - applications.push_back(application); + this->applications.push_back(application); return true; } bool Environment::RemoveApplication(std::size_t application_index) { - assert(!applications.empty()); - assert(application_index < applications.size()); + assert(!this->applications.empty()); + assert(application_index < this->applications.size()); - if (applications.size() == 1u) { - applications.clear(); + if (this->applications.size() == 1u) { + this->applications.clear(); return true; } std::vector new_applications; - new_applications.reserve(applications.size() - 1); + new_applications.reserve(this->applications.size() - 1); - for (std::size_t i = 0, n = applications.size(); i < n; ++i) { + for (std::size_t i = 0, n = this->applications.size(); i < n; ++i) { if (i == application_index) continue; - new_applications.push_back(applications[i]); + new_applications.push_back(this->applications[i]); } - std::swap(applications, new_applications); + std::swap(this->applications, new_applications); return true; } const Application& Environment::GetActiveApplication() const { - assert(!applications.empty()); + assert(!this->applications.empty()); - for (std::size_t i = 0, n = applications.size(); i < n; ++i) { - if (applications[i].app_name == this->active_application) { - return applications[i]; + for (std::size_t i = 0, n = this->applications.size(); i < n; ++i) { + if (this->applications[i].app_name == this->active_application) { + return this->applications[i]; } } - return applications[0]; // Not found, but the list is present, so return the first item. + return this->applications[0]; // Not found, but the list is present, so return the first item. } const Application& Environment::GetApplication(std::size_t application_index) const { - assert(application_index < applications.size()); + assert(application_index < this->applications.size()); - return applications[application_index]; + return this->applications[application_index]; } Application& Environment::GetApplication(std::size_t application_index) { - assert(application_index < applications.size()); + assert(application_index < this->applications.size()); - return applications[application_index]; + return this->applications[application_index]; } bool Environment::GetPerApplicationConfig() const { return this->use_per_application_configuration; } @@ -484,17 +487,19 @@ void Environment::SetMode(LayersMode mode) { this->layers_mode = mode; } void Environment::Set(LayoutState state, const QByteArray& data) { assert(state >= LAYOUT_FIRST && state <= LAYOUT_LAST); - layout_states[state] = data; + this->layout_states[state] = data; } const QByteArray& Environment::Get(LayoutState state) const { assert(state >= LAYOUT_FIRST && state <= LAYOUT_LAST); - return layout_states[state]; + return this->layout_states[state]; } bool Environment::IsDefaultConfigurationInit(const std::string& default_configuration_filename) const { - for (std::size_t i = 0, n = default_configuration_filenames.size(); i < n; ++i) { - if (default_configuration_filenames[i] == default_configuration_filename) return true; + for (std::size_t i = 0, n = this->default_configuration_filenames.size(); i < n; ++i) { + if (this->default_configuration_filenames[i] == default_configuration_filename) { + return true; + } } return false; diff --git a/vkconfig_core/environment.h b/vkconfig_core/environment.h index b6ee919936..44101fe310 100644 --- a/vkconfig_core/environment.h +++ b/vkconfig_core/environment.h @@ -31,8 +31,6 @@ #include #include -enum LayersMode { LAYERS_MODE_BY_APPLICATIONS = 0, LAYERS_MODE_BY_CONFIGURATOR_RUNNING, LAYERS_MODE_BY_CONFIGURATOR_ALL_DISABLED }; - enum LayoutState { VKCONFIG2_LAYOUT_MAIN_GEOMETRY = 0, VKCONFIG2_LAYOUT_MAIN_WINDOW_STATE, diff --git a/vkconfig_core/override.cpp b/vkconfig_core/override.cpp index 009b9cc0d1..c1c2ebe23b 100644 --- a/vkconfig_core/override.cpp +++ b/vkconfig_core/override.cpp @@ -32,6 +32,7 @@ #include +#include #include // Create and write VkLayer_override.json file @@ -143,7 +144,7 @@ bool WriteLayersOverride(const Environment& environment, const std::vector layers; + int stderr_log_flags; +}; + +static std::vector GetStderrLogStrings(int stderr_log_flags) { + static const char* table[] = {"error", "warn", "info", "debug"}; + static_assert(countof(table) == LOG_COUNT, "The tranlation table size doesn't match the enum number of elements"); + + std::vector result; + + for (int i = LOG_FIRST, n = LOG_COUNT; i < n; ++i) { + if (stderr_log_flags & (1 << i)) { + result.push_back(table[i]); + } + } + + return result; +} + +static QJsonObject CreateJsonSettingObject(const LoaderSettings& loader_settings) { + QJsonArray json_app_keys; + json_app_keys.append(loader_settings.executable_path.c_str()); + + QJsonArray json_layers; + for (std::size_t j = 0, o = loader_settings.layers.size(); j < o; ++j) { + const LayerSettings& layer = loader_settings.layers[j]; + + QJsonObject json_layer; + json_layer.insert("name", layer.name.c_str()); + json_layer.insert("path", layer.path.c_str()); + json_layer.insert("control", GetString(layer.control)); + json_layer.insert("treat_as_implicit_manifest", layer.implicit); + json_layers.append(json_layer); + } + + QJsonArray json_stderr_log; + const std::vector& stderr_log = GetStderrLogStrings(loader_settings.stderr_log_flags); + for (std::size_t i = 0, n = stderr_log.size(); i < n; ++i) { + json_stderr_log.append(stderr_log[i].c_str()); + } + + QJsonObject json_settings; + json_settings.insert("app_keys", json_app_keys); + json_settings.insert("layers", json_layers); + json_settings.insert("stderr_log", json_stderr_log); + return json_settings; +} + +// Create and write vk_loader_settings.json file +bool WriteLoaderSettings(const Environment& environment, const std::vector& available_layers, + const Configuration& configuration, const std::string& layers_path) { + assert(!layers_path.empty()); + assert(QFileInfo(layers_path.c_str()).absoluteDir().exists()); + + std::vector loader_settings_array; + + if (environment.GetPerApplicationConfig()) { + for (std::size_t i = 0, n = environment.GetApplications().size(); i < n; ++i) { + LoaderSettings loader_settings; + + const Application& application = environment.GetApplication(i); + + switch (application.layers_mode) { + case LAYERS_MODE_BY_APPLICATIONS: { + } break; + case LAYERS_MODE_BY_CONFIGURATOR_RUNNING: { + } break; + case LAYERS_MODE_BY_CONFIGURATOR_ALL_DISABLED: { + } break; + } + + loader_settings_array.push_back(loader_settings); + } + } else { + const std::string& selected_configuration = environment.GetSelectedConfiguration(); + + LoaderSettings loader_settings; + loader_settings.stderr_log_flags = 0; + + if (environment.GetMode() != LAYERS_MODE_BY_APPLICATIONS) { + for (std::size_t i = 0, n = configuration.parameters.size(); i < n; ++i) { + LayerSettings layer_settings; + + const Parameter& parameter = configuration.parameters[i]; + if (!(parameter.platform_flags & (1 << VKC_PLATFORM))) { + continue; + } + + if (parameter.state != LAYER_STATE_OVERRIDDEN) { + continue; + } + + const Layer* layer = FindByKey(available_layers, parameter.key.c_str()); + if (layer == nullptr) { + continue; + } + + // Extract just the path + assert(!layer->manifest_path.empty()); + layer_settings.name = layer->key; + layer_settings.path = QFileInfo(layer->manifest_path.c_str()).absolutePath().toStdString(); + layer_settings.control = LAYER_CONTROL_AUTO; // TODO + layer_settings.implicit = layer->type == LAYER_TYPE_IMPLICIT; + + loader_settings.layers.push_back(layer_settings); + } + } + + loader_settings_array.push_back(loader_settings); + } + + QJsonObject root; + root.insert("file_format_version", "1.0.0"); + if (loader_settings_array.size() > 1) { + QJsonArray json_settings_array; + for (std::size_t i = 0, n = loader_settings_array.size(); i < n; ++i) { + json_settings_array.append(CreateJsonSettingObject(loader_settings_array[i])); + } + root.insert("settings_array", json_settings_array); + } else { + root.insert("settings", CreateJsonSettingObject(loader_settings_array[0])); + } + QJsonDocument doc(root); + + QFile json_file(layers_path.c_str()); + const bool result_layers_file = json_file.open(QIODevice::WriteOnly | QIODevice::Text); + assert(result_layers_file); + json_file.write(doc.toJson()); + json_file.close(); + + return result_layers_file; +} + // Create and write vk_layer_settings.txt file -bool WriteSettingsOverride(const std::vector& available_layers, const Configuration& configuration, - const std::string& settings_path) { +bool WriteLayersSettings(const std::vector& available_layers, const Configuration& configuration, + const std::string& settings_path) { if (settings_path.empty() || !QFileInfo(settings_path.c_str()).absoluteDir().exists()) { fprintf(stderr, "Cannot open file %s\n", settings_path.c_str()); exit(1); @@ -294,7 +464,7 @@ bool OverrideConfiguration(const Environment& environment, const std::vector& available_layers, - const Configuration& configuration, const std::string& settings_path); +// Write the settings file +bool WriteLayersSettings(const std::vector& available_layers, const Configuration& configuration, + const std::string& settings_path); diff --git a/vkconfig_core/parameter.cpp b/vkconfig_core/parameter.cpp index 288272f704..23a9304338 100644 --- a/vkconfig_core/parameter.cpp +++ b/vkconfig_core/parameter.cpp @@ -197,7 +197,13 @@ std::size_t CountExcludedLayers(const std::vector& parameters, const std::vector GatherParameters(const std::vector& parameters, const std::vector& available_layers) { std::vector gathered_parameters; - + /* + Parameter application_enabled_layers; + application_enabled_layers.key = "Application Enabled Layers"; + application_enabled_layers.control = LAYER_CONTROL_APPLICATIONS; + application_enabled_layers.overridden_rank = Parameter::NO_RANK; + gathered_parameters.push_back(application_enabled_layers); + */ // Loop through the layers. They are expected to be in order for (std::size_t i = 0, n = parameters.size(); i < n; ++i) { const Parameter& parameter = parameters[i]; @@ -222,7 +228,13 @@ std::vector GatherParameters(const std::vector& parameters } OrderParameter(gathered_parameters, available_layers); - + /* + Parameter unordered_layer_location; + unordered_layer_location.key = "Unordered Layers"; + unordered_layer_location.control = LAYER_CONTROL_UNORDERED; + unordered_layer_location.overridden_rank = 999; + gathered_parameters.push_back(unordered_layer_location); + */ return gathered_parameters; } diff --git a/vkconfig_core/parameter.h b/vkconfig_core/parameter.h index ff5477e493..beed5f3c6a 100644 --- a/vkconfig_core/parameter.h +++ b/vkconfig_core/parameter.h @@ -35,6 +35,19 @@ enum ParameterRank { PARAMETER_RANK_EXPLICIT_AVAILABLE }; +enum LayerControl { + LAYER_CONTROL_OFF = 0, + LAYER_CONTROL_ON, + LAYER_CONTROL_AUTO, + LAYER_CONTROL_APPLICATIONS, + LAYER_CONTROL_UNORDERED, + + LAYER_CONTROL_FIRST = LAYER_CONTROL_OFF, + LAYER_CONTROL_LAST = LAYER_CONTROL_UNORDERED +}; + +enum { LAYER_CONTROL_COUNT = LAYER_CONTROL_LAST - LAYER_CONTROL_FIRST + 1 }; + struct Parameter { static const int NO_RANK = -1; @@ -43,7 +56,7 @@ struct Parameter { } Parameter(const std::string& key, const LayerState state) - : key(key), state(state), platform_flags(PLATFORM_DESKTOP_BIT), overridden_rank(NO_RANK) { + : key(key), state(state), control(LAYER_CONTROL_AUTO), platform_flags(PLATFORM_DESKTOP_BIT), overridden_rank(NO_RANK) { assert(true); } @@ -51,6 +64,7 @@ struct Parameter { std::string key; LayerState state; + LayerControl control; int platform_flags; SettingDataSet settings; int overridden_rank; diff --git a/vkconfig_core/test/test_override.cpp b/vkconfig_core/test/test_override.cpp index c4656a2bbf..7f14f7cc38 100644 --- a/vkconfig_core/test/test_override.cpp +++ b/vkconfig_core/test/test_override.cpp @@ -35,8 +35,8 @@ static const std::vector SUPPORTED_CONFIG_FILES = {"_2_2_3", "_2_2_ extern bool WriteLayersOverride(const Environment& environment, const std::vector& available_layers, const Configuration& configuration, const std::string& layers_path); -extern bool WriteSettingsOverride(const std::vector& available_layers, const Configuration& configuration, - const std::string& settings_path); +extern bool WriteLayersSettings(const std::vector& available_layers, const Configuration& configuration, + const std::string& settings_path); extern bool EraseLayersOverride(const std::string& layers_path); @@ -59,7 +59,7 @@ TEST(test_override, write_erase_2_2_2) { EXPECT_TRUE(!configuration.parameters.empty()); EXPECT_EQ(true, WriteLayersOverride(env, layer_manager.selected_layers, configuration, "." + LAYERS)); - EXPECT_EQ(true, WriteSettingsOverride(layer_manager.selected_layers, configuration, "." + SETTINGS)); + EXPECT_EQ(true, WriteLayersSettings(layer_manager.selected_layers, configuration, "." + SETTINGS)); QFile file_layers_override_ref((":" + LAYERS).c_str()); const bool result_layers_override_ref = file_layers_override_ref.open(QIODevice::ReadOnly | QIODevice::Text);