diff --git a/vkconfig/configurator.cpp b/vkconfig/configurator.cpp deleted file mode 100644 index 87d1314288..0000000000 --- a/vkconfig/configurator.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Authors: - * - Lenny Komow - * - Richard S. Wright Jr. - * - Christophe Riccio - */ - -#include "configurator.h" -#include "vulkan_util.h" - -#include "dialog_layers.h" - -#include "../vkconfig_core/util.h" -#include "../vkconfig_core/path.h" -#include "../vkconfig_core/override.h" -#include "../vkconfig_core/alert.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -Configurator &Configurator::Get(const std::string &VULKAN_SDK) { - static Configurator configurator(VULKAN_SDK); - return configurator; -} - -Configurator::Configurator(const std::string &VULKAN_SDK) - : path(VULKAN_SDK, SUPPORTED_CONFIG_FILES), environment(path), layers(environment), configurations(environment) {} - -Configurator::~Configurator() { - configurations.SaveAllConfigurations(layers.selected_layers); - - SurrenderConfiguration(environment); -} - -bool Configurator::Init() { - std::string selected_configuration = this->environment.GetSelectedConfiguration(); - - this->ActivateConfiguration(""); - - this->UpdateDevices(); - - // Load simple app settings, the additional search paths, and the - // override app list. - this->layers.LoadAllInstalledLayers(); - - QSettings settings; - if (settings.value("crashed", QVariant(false)).toBool()) { - settings.setValue("crashed", false); - - if (Alert::ConfiguratorCrashed() == QMessageBox::No) { - this->configurations.LoadAllConfigurations(this->layers.selected_layers); - } - } else { - this->configurations.LoadAllConfigurations(this->layers.selected_layers); - } - - if (this->configurations.Empty()) { - this->configurations.ResetDefaultsConfigurations(layers.selected_layers); - } else { - this->configurations.FirstDefaultsConfigurations(layers.selected_layers); - } - - this->ActivateConfiguration(selected_configuration); - - return true; -} - -void Configurator::ActivateConfiguration(const std::string &configuration_name) { - Configuration *configuration = nullptr; - if (!configuration_name.empty()) { - configuration = FindByKey(this->configurations.available_configurations, configuration_name.c_str()); - } - - if (configuration_name.empty()) { - this->environment.SetSelectedConfiguration(""); - this->configurations.Configure(this->layers.selected_layers); - } else if (configuration == nullptr) { - QMessageBox alert; - alert.QDialog::setWindowTitle("Vulkan layers configuration is missing..."); - const std::string text = format("%s couldn't find '%s' layers configuration.", VKCONFIG_NAME, configuration_name.c_str()); - alert.setText(text.c_str()); - alert.setInformativeText("Vulkan Configurator is switching to Layers Controlled by Vulkan Application mode"); - alert.setIcon(QMessageBox::Critical); - alert.exec(); - - this->environment.SetSelectedConfiguration(""); - this->environment.SetMode(LAYERS_MODE_BY_APPLICATIONS); - this->configurations.Configure(this->layers.selected_layers); - } else { - // If the layers paths are differents, we need to reload the layers and the configurations - const std::vector paths = this->environment.GetUserDefinedLayersPaths(USER_DEFINED_LAYERS_PATHS_GUI); - if (configuration->user_defined_paths != paths) { - this->configurations.SaveAllConfigurations(this->layers.selected_layers); - this->environment.SetPerConfigUserDefinedLayersPaths(configuration->user_defined_paths); - this->layers.LoadAllInstalledLayers(); - this->configurations.LoadAllConfigurations(this->layers.selected_layers); - } - - this->environment.SetSelectedConfiguration(configuration_name.c_str()); - - std::string missing_layer; - if (::HasMissingLayer(configuration->parameters, layers.selected_layers, missing_layer)) { - QMessageBox alert; - alert.QDialog::setWindowTitle("Vulkan layer missing..."); - alert.setText(format("%s couldn't find '%s' layer required by '%s' configuration:", VKCONFIG_NAME, - missing_layer.c_str(), configuration->key.c_str()) - .c_str()); - alert.setInformativeText("Do you want to edit the configuration to locate the layer?"); - alert.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - alert.setDefaultButton(QMessageBox::Yes); - alert.setIcon(QMessageBox::Warning); - if (alert.exec() == QMessageBox::Yes) { - LayersDialog dlg(nullptr, *configuration); - dlg.exec(); - - ActivateConfiguration(configuration->key); - } - } else { - this->configurations.Configure(this->layers.selected_layers); - } - } -} - -void Configurator::UpdateDevices() { - QLibrary library(GetVulkanLibrary()); - if (!library.load()) { - return; - } - - VkInstance instance = VK_NULL_HANDLE; - VkResult err = CreateInstance(library, instance, false); - - if (err != VK_SUCCESS) { - err = CreateInstance(library, instance, true); - if (err != VK_SUCCESS) { - return; - } - } - - PFN_vkEnumeratePhysicalDevices pfnEnumeratePhysicalDevices = - (PFN_vkEnumeratePhysicalDevices)library.resolve("vkEnumeratePhysicalDevices"); - PFN_vkDestroyInstance pfnDestroyInstance = (PFN_vkDestroyInstance)library.resolve("vkDestroyInstance"); - PFN_vkGetPhysicalDeviceProperties pfnGetPhysicalDeviceProperties = - (PFN_vkGetPhysicalDeviceProperties)library.resolve("vkGetPhysicalDeviceProperties"); - - if (pfnEnumeratePhysicalDevices == nullptr || pfnDestroyInstance == nullptr || pfnGetPhysicalDeviceProperties == nullptr) { - return; - } - - uint32_t gpu_count = 0; - err = pfnEnumeratePhysicalDevices(instance, &gpu_count, NULL); - assert(!err); - - std::vector devices; - if (gpu_count > 0) { - devices.resize(gpu_count); - - err = pfnEnumeratePhysicalDevices(instance, &gpu_count, &devices[0]); - assert(!err); - } - - this->device_names.clear(); - for (std::size_t i = 0, n = devices.size(); i < n; ++i) { - VkPhysicalDeviceProperties properties; - pfnGetPhysicalDeviceProperties(devices[i], &properties); - - this->device_names.push_back(properties.deviceName); - } - - pfnDestroyInstance(instance, NULL); -} - -bool Configurator::SupportDifferentLayerVersions(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.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"); -} - -void Configurator::ResetToDefault(bool hard) { - if (hard) { - this->environment.Reset(Environment::CLEAR); - this->layers.LoadAllInstalledLayers(); - this->configurations.ResetDefaultsConfigurations(this->layers.selected_layers); - - this->ActivateConfiguration(this->environment.GetSelectedConfiguration()); - } else { - this->configurations.ReloadDefaultsConfigurations(this->layers.selected_layers); - } -} - -std::vector Configurator::GetDeviceNames() const { return device_names; } diff --git a/vkconfig/main_gui.cpp b/vkconfig/main_gui.cpp deleted file mode 100644 index f1c4342abf..0000000000 --- a/vkconfig/main_gui.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Authors: - * - Christophe Riccio - */ - -#include "main_gui.h" - -#include "mainwindow.h" - -#include "../vkconfig_core/alert.h" -#include "../vkconfig_core/version.h" -#include "../vkconfig_core/application_singleton.h" - -#include -#include - -int run_gui(int argc, char* argv[], const CommandLine& command_line) { - QCoreApplication::setOrganizationName("LunarG"); - QCoreApplication::setOrganizationDomain("lunarg.com"); - - // This is used by QSettings for .ini, registry, and .plist files. - // It needs to not have spaces in it, and by default is the same as - // the executable name. If we rename the executable at a later date, - // keeping this as 'vkconfig' will ensure that it picks up the - // settings from the previous version (assuming that's ever an issue) - QCoreApplication::setApplicationName(VKCONFIG_SHORT_NAME); - - // Older Qt versions do not have this. Dynamically check the version - // of Qt since it's just an enumerant. Versions 5.6.0 and later have - // high dpi support. We really don't need to check the 5, but for - // the sake of completeness and mabye compatibility with qt 6. - // Also ignoring the trailing point releases - const char* version = qVersion(); - int version_major, version_minor; - sscanf(version, "%d.%d", &version_major, &version_minor); - if (version_major >= 5 && version_minor >= 6) { - // Qt::AA_EnableHighDpiScaling = 20 from qnamespace.h in Qt 5.6 or later - QCoreApplication::setAttribute((Qt::ApplicationAttribute)20); - } - - QApplication app(argc, argv); - - // This has to go after the construction of QApplication in - // order to use a QMessageBox and avoid some QThread warnings. - ApplicationSingleton singleton("vkconfig_single_instance"); - - while (!singleton.IsFirstInstance()) { - if (Alert::ConfiguratorSingleton() == QMessageBox::Cancel) { - return -1; - } - } - - // We simply cannot run without any layers - Configurator& configurator = Configurator::Get(command_line.command_vulkan_sdk); - - if (!configurator.Init()) { - return -1; - } - - // The main GUI is driven here - MainWindow main_window; - main_window.show(); - - return app.exec(); -} diff --git a/vkconfig_core/configuration.cpp b/vkconfig_core/configuration.cpp index db21fa7a75..09c56e00a4 100644 --- a/vkconfig_core/configuration.cpp +++ b/vkconfig_core/configuration.cpp @@ -167,11 +167,15 @@ bool Configuration::Load(const Path& full_path, const LayerManager& layers) { const std::string& version = ReadStringValue(json_layer_object, "version"); parameter.api_version = version == "latest" ? Version::LATEST : Version(version.c_str()); } + if (json_layer_object.value("type") != QJsonValue::Undefined) { + parameter.type = GetLayerType(json_layer_object.value("type").toString().toStdString().c_str()); + } const Layer* layer = layers.Find(parameter.key, parameter.api_version); if (layer != nullptr) { parameter.manifest = layer->manifest_path; + parameter.type = layer->type; } if (json_layer_object.value("manifest") != QJsonValue::Undefined) { @@ -247,6 +251,7 @@ bool Configuration::Save(const Path& full_path, bool exporter) const { QJsonObject json_layer; json_layer.insert("name", parameter.key.c_str()); + json_layer.insert("type", ::GetToken(parameter.type)); if (parameter.builtin != LAYER_BUILTIN_NONE) { json_layer.insert("builtin", GetToken(parameter.builtin)); } @@ -433,6 +438,7 @@ void Configuration::SwitchLayerVersion(const LayerManager& layers, const std::st const Layer* new_layer = layers.FindFromManifest(manifest_path); parameter->api_version = new_layer->api_version; + parameter->type = new_layer->type; parameter->manifest = new_layer->manifest_path; ::CollectDefaultSettingData(new_layer->settings, parameter->settings); } @@ -442,8 +448,8 @@ void Configuration::SwitchLayerLatest(const LayerManager& layers, const std::str assert(parameter != nullptr); const Layer* new_layer = layers.Find(layer_key, Version::LATEST); - parameter->api_version = Version::LATEST; + parameter->type = new_layer->type; parameter->manifest = new_layer->manifest_path; ::CollectDefaultSettingData(new_layer->settings, parameter->settings); } @@ -473,6 +479,7 @@ void Configuration::GatherParameters(const LayerManager& layers) { Parameter parameter; parameter.key = layer->key; + parameter.type = layer->type; parameter.control = this->default_control; parameter.api_version = Version::LATEST; parameter.manifest = layer->manifest_path; diff --git a/vkconfig_core/configurator.cpp b/vkconfig_core/configurator.cpp index d3af802ef5..c9e740464b 100644 --- a/vkconfig_core/configurator.cpp +++ b/vkconfig_core/configurator.cpp @@ -879,8 +879,8 @@ std::string Configurator::GenerateVulkanStatus() const { log += this->layers.Log(); log += this->configurations.Log(); log += this->executables.Log(); - log += "Vulkan Loader Log:\n"; - log += ::GenerateLoaderLog(); + // log += "Vulkan Loader Log:\n"; + // log += ::GenerateLoaderLog(); return log; } diff --git a/vkconfig_core/parameter.h b/vkconfig_core/parameter.h index f5798a4255..fbf889a053 100644 --- a/vkconfig_core/parameter.h +++ b/vkconfig_core/parameter.h @@ -47,6 +47,7 @@ struct Parameter { bool ApplyPresetSettings(const LayerPreset& preset); std::string key; + LayerType type = LAYER_TYPE_EXPLICIT; LayerControl control = LAYER_CONTROL_AUTO; LayerBuiltin builtin = LAYER_BUILTIN_NONE; int platform_flags = PLATFORM_DESKTOP_BIT; diff --git a/vkconfig_core/type_hide_message.cpp b/vkconfig_core/type_hide_message.cpp index 3942a860b4..aa6a1c3ab0 100644 --- a/vkconfig_core/type_hide_message.cpp +++ b/vkconfig_core/type_hide_message.cpp @@ -26,13 +26,21 @@ #include const char* GetToken(HideMessageType value) { - static const char* TOKENS[]{"HIDE_MESSAGE_NEED_APPLICATION_RESTART", "HIDE_MESSAGE_USE_SYSTEM_TRAY", - "HIDE_MESSAGE_WIDGET_SETTING_FLOAT", "HIDE_MESSAGE_WIDGET_SETTING_INT", - "HIDE_MESSAGE_WIDGET_SETTING_FRAMES", "HIDE_MESSAGE_NOTIFICATION_EXPORT", - "HIDE_MESSAGE_NOTIFICATION_LAYERS_LOADED", "HIDE_MESSAGE_NOTIFICATION_UNORDERED_LAYER", - "HIDE_MESSAGE_WARN_REMOVE_EXECUTABLE", "HIDE_MESSAGE_WARN_REMOVE_EXECUTABLE_OPTIONS", - "HIDE_MESSAGE_WARN_MISSING_LAYERS_IGNORE", "HIDE_MESSAGE_WARN_CORE_SHADER_IGNORE", - "HIDE_MESSAGE_QUESTION_REMOVING_LAYERS_PATH", "HIDE_MESSAGE_ERROR_32BIT"}; + static const char* TOKENS[]{"HIDE_MESSAGE_NEED_APPLICATION_RESTART", + "HIDE_MESSAGE_USE_SYSTEM_TRAY", + "HIDE_MESSAGE_CRITICAL_IMPLICIT_LAYER_OVERRIDE", + "HIDE_MESSAGE_WIDGET_SETTING_FLOAT", + "HIDE_MESSAGE_WIDGET_SETTING_INT", + "HIDE_MESSAGE_WIDGET_SETTING_FRAMES", + "HIDE_MESSAGE_NOTIFICATION_EXPORT", + "HIDE_MESSAGE_NOTIFICATION_LAYERS_LOADED", + "HIDE_MESSAGE_NOTIFICATION_UNORDERED_LAYER", + "HIDE_MESSAGE_WARN_REMOVE_EXECUTABLE", + "HIDE_MESSAGE_WARN_REMOVE_EXECUTABLE_OPTIONS", + "HIDE_MESSAGE_WARN_MISSING_LAYERS_IGNORE", + "HIDE_MESSAGE_WARN_CORE_SHADER_IGNORE", + "HIDE_MESSAGE_QUESTION_REMOVING_LAYERS_PATH", + "HIDE_MESSAGE_ERROR_32BIT"}; static_assert(std::size(TOKENS) == HIDE_MESSAGE_COUNT); if (value >= HIDE_MESSAGE_FIRST && value <= HIDE_MESSAGE_LAST) { diff --git a/vkconfig_core/type_hide_message.h b/vkconfig_core/type_hide_message.h index 80becbe0cb..103742c31c 100644 --- a/vkconfig_core/type_hide_message.h +++ b/vkconfig_core/type_hide_message.h @@ -26,6 +26,7 @@ enum HideMessageType { HIDE_MESSAGE_NEED_APPLICATION_RESTART = 0, HIDE_MESSAGE_USE_SYSTEM_TRAY, + HIDE_MESSAGE_CRITICAL_IMPLICIT_LAYER_OVERRIDE, HIDE_MESSAGE_WIDGET_SETTING_FLOAT, HIDE_MESSAGE_WIDGET_SETTING_INT, HIDE_MESSAGE_WIDGET_SETTING_FRAMES, diff --git a/vkconfig_core/type_layer_control.cpp b/vkconfig_core/type_layer_control.cpp index 4436208bcc..551610361a 100644 --- a/vkconfig_core/type_layer_control.cpp +++ b/vkconfig_core/type_layer_control.cpp @@ -24,37 +24,37 @@ #include #include +LayerControl GetLayerControl(const char* token) { + for (int i = LAYER_CONTROL_FIRST, l = LAYER_CONTROL_LAST; i <= l; ++i) { + const LayerControl type = static_cast(i); + if (ToLowerCase(::GetToken(type)) == ToLowerCase(token)) { + return type; + } + } + + return LAYER_CONTROL_AUTO; +} + // These names are requied by the Vulkan Loader settings file const char* GetToken(LayerControl control) { static const char* TABLE[] = { "auto", // LAYER_CONTROL_AUTO + "discard", // LAYER_CONTROL_DISCARD "on", // LAYER_CONTROL_ON "off", // LAYER_CONTROL_OFF - "discard", // LAYER_CONTROL_DISCARD }; static_assert(std::size(TABLE) == LAYER_CONTROL_COUNT); return TABLE[control]; } -LayerControl GetLayerControl(const char* token) { - for (int i = LAYER_CONTROL_FIRST, l = LAYER_CONTROL_LAST; i <= l; ++i) { - const LayerControl type = static_cast(i); - if (ToLowerCase(::GetToken(type)) == ToLowerCase(token)) { - return type; - } - } - - return LAYER_CONTROL_AUTO; -} - // These names are requied by the Vulkan Loader settings file const char* GetLabel(LayerControl control) { static const char* TABLE[] = { "Auto", // LAYER_CONTROL_AUTO + "Discard", // LAYER_CONTROL_DISCARD "Enable", // LAYER_CONTROL_ON "Disable", // LAYER_CONTROL_OFF - "Discard", // LAYER_CONTROL_DISCARD }; static_assert(std::size(TABLE) == LAYER_CONTROL_COUNT); @@ -64,9 +64,9 @@ const char* GetLabel(LayerControl control) { const char* GetDescription(LayerControl control) { static const char* TOKENS[] = { "Explicit layers are disabled by default and implicit layers are enabled by default.", // LAYER_CONTROL_AUTO + "Discard the layer, don't notify the Vulkan Loader this layer exist.", // LAYER_CONTROL_DISCARD "Enable the layer, insuring its execution.", // LAYER_CONTROL_ON "Disable the layer, preventing its execution.", // LAYER_CONTROL_OFF - "Discard the layer, don't notify the Vulkan Loader this layer exist.", // LAYER_CONTROL_DISCARD }; static_assert(std::size(TOKENS) == LAYER_CONTROL_COUNT); diff --git a/vkconfig_core/type_layer_control.h b/vkconfig_core/type_layer_control.h index f429631218..03658803a2 100644 --- a/vkconfig_core/type_layer_control.h +++ b/vkconfig_core/type_layer_control.h @@ -22,15 +22,21 @@ enum LayerControl { LAYER_CONTROL_AUTO = 0, + LAYER_CONTROL_DISCARD, LAYER_CONTROL_ON, LAYER_CONTROL_OFF, - LAYER_CONTROL_DISCARD, LAYER_CONTROL_FIRST = LAYER_CONTROL_AUTO, - LAYER_CONTROL_LAST = LAYER_CONTROL_DISCARD, + LAYER_CONTROL_LAST = LAYER_CONTROL_OFF, + + LAYER_CONTROL_UNORDERED_FIRST = LAYER_CONTROL_AUTO, + LAYER_CONTROL_UNORDERED_LAST = LAYER_CONTROL_DISCARD, }; -enum { LAYER_CONTROL_COUNT = LAYER_CONTROL_LAST - LAYER_CONTROL_FIRST + 1 }; +enum { + LAYER_CONTROL_COUNT = LAYER_CONTROL_LAST - LAYER_CONTROL_FIRST + 1, + LAYER_CONTROL_UNORDERED_COUNT = LAYER_CONTROL_UNORDERED_LAST - LAYER_CONTROL_UNORDERED_FIRST + 1 +}; LayerControl GetLayerControl(const char* token); const char* GetToken(LayerControl control); diff --git a/vkconfig_gui/settings_tree.cpp b/vkconfig_gui/settings_tree.cpp index 1cb318e953..53bd080d09 100644 --- a/vkconfig_gui/settings_tree.cpp +++ b/vkconfig_gui/settings_tree.cpp @@ -425,11 +425,13 @@ void SettingsTreeManager::Refresh(RefreshAreas refresh_areas) { this->ui->configurations_settings->blockSignals(false); - if (!(configurator.Get(HIDE_MESSAGE_NEED_APPLICATION_RESTART))) { - configurator.Set(HIDE_MESSAGE_NEED_APPLICATION_RESTART); + /* + if (!(configurator.Get(HIDE_MESSAGE_NEED_APPLICATION_RESTART))) { + configurator.Set(HIDE_MESSAGE_NEED_APPLICATION_RESTART); - Alert::ConfiguratorRestart(); - } + Alert::ConfiguratorRestart(); + } + */ // Refresh layer configuration configurator.Override(OVERRIDE_AREA_LAYERS_SETTINGS_BIT); diff --git a/vkconfig_gui/widget_tab_configurations_layer.cpp b/vkconfig_gui/widget_tab_configurations_layer.cpp index 9728c00b8d..8574049c70 100644 --- a/vkconfig_gui/widget_tab_configurations_layer.cpp +++ b/vkconfig_gui/widget_tab_configurations_layer.cpp @@ -25,6 +25,8 @@ #include "../vkconfig_core/configurator.h" +#include + ConfigurationLayerWidget::ConfigurationLayerWidget(TabConfigurations *tab, const Parameter ¶meter) : layer_name(parameter.key), tab(tab) { const Configurator &configurator = Configurator::Get(); @@ -33,7 +35,9 @@ ConfigurationLayerWidget::ConfigurationLayerWidget(TabConfigurations *tab, const this->layer_state = new ComboBox(this); this->layer_state->setSizeAdjustPolicy(QComboBox::AdjustToContents); - for (int i = LAYER_CONTROL_FIRST; i <= LAYER_CONTROL_LAST; ++i) { + const int first = parameter.builtin == LAYER_BUILTIN_UNORDERED ? LAYER_CONTROL_UNORDERED_FIRST : LAYER_CONTROL_FIRST; + const int last = parameter.builtin == LAYER_BUILTIN_UNORDERED ? LAYER_CONTROL_UNORDERED_LAST : LAYER_CONTROL_LAST; + for (int i = first; i <= last; ++i) { const LayerControl layer_control = static_cast(i); std::string label = ::GetLabel(layer_control); /* @@ -44,7 +48,6 @@ ConfigurationLayerWidget::ConfigurationLayerWidget(TabConfigurations *tab, const this->layer_state->addItem(label.c_str()); this->layer_state->setItemData(i, ::GetDescription(layer_control), Qt::ToolTipRole); } - this->layer_state->setCurrentIndex(parameter.control); if (parameter.control == LAYER_CONTROL_AUTO && layer != nullptr) { @@ -132,6 +135,31 @@ void ConfigurationLayerWidget::on_layer_state_currentIndexChanged(int index) { Configuration *configuration = configurator.GetActiveConfiguration(); Parameter *parameter = configuration->Find(this->layer_name); if (parameter != nullptr) { + if (!(configurator.Get(HIDE_MESSAGE_CRITICAL_IMPLICIT_LAYER_OVERRIDE))) { + if (parameter->type == LAYER_TYPE_IMPLICIT && control != LAYER_CONTROL_AUTO) { + const char *text = + "%s was overridden but it is an implicit layer. This may cause undefined behavior, including crashes."; + + QMessageBox alert; + alert.QDialog::setWindowTitle("An Vulkan implicit layer was overridden..."); + alert.setText(format(text, this->layer_name.c_str()).c_str()); + alert.setInformativeText("Do you want to continue?"); + alert.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + alert.setIcon(QMessageBox::Critical); + alert.setCheckBox(new QCheckBox("Do not show again.")); + int selection = alert.exec(); + + if (alert.checkBox()->isChecked()) { + configurator.Set(HIDE_MESSAGE_CRITICAL_IMPLICIT_LAYER_OVERRIDE); + } + + if (selection == QMessageBox::No) { + this->layer_state->setCurrentIndex(LAYER_CONTROL_AUTO); + return; + } + } + } + parameter->control = control; this->layer_state->setToolTip(GetDescription(control));