From ef51ab81ddd838785eadd9fc4dd80f7f052e1421 Mon Sep 17 00:00:00 2001 From: Christophe Date: Mon, 15 Jul 2024 15:14:30 +0200 Subject: [PATCH] vkconfig3: Enable layer version selection --- vkconfig_cmd/main_layers.cpp | 2 +- vkconfig_core/configuration.cpp | 99 +++++++++----- vkconfig_core/configuration.h | 8 +- vkconfig_core/configuration_manager.cpp | 21 +-- vkconfig_core/configuration_manager.h | 2 +- .../configurations/3.0.0/API dump.json | 3 +- .../3.0.0/Crash Diagnostic.json | 3 +- .../configurations/3.0.0/Frame Capture.json | 3 +- .../configurations/3.0.0/Portability.json | 53 +------- .../configurations/3.0.0/Synchronization.json | 6 +- .../configurations/3.0.0/Validation.json | 3 +- vkconfig_core/configurator.cpp | 2 +- vkconfig_core/parameter.cpp | 8 +- vkconfig_core/parameter.h | 19 ++- vkconfig_core/path.cpp | 9 +- vkconfig_core/test/Configuration 3.0.0.json | 1 + vkconfig_core/test/test_configuration.cpp | 6 +- .../test/test_configuration_built_in.cpp | 10 +- vkconfig_gui/configuration_layer_widget.cpp | 128 ++++++++++++++++++ vkconfig_gui/configuration_layer_widget.h | 50 +++++++ vkconfig_gui/mainwindow.cpp | 45 +----- vkconfig_gui/mainwindow.h | 92 +------------ vkconfig_gui/mainwindow.ui | 7 +- vkconfig_gui/vkconfig.pro | 2 + 24 files changed, 317 insertions(+), 265 deletions(-) create mode 100644 vkconfig_gui/configuration_layer_widget.cpp create mode 100644 vkconfig_gui/configuration_layer_widget.h diff --git a/vkconfig_cmd/main_layers.cpp b/vkconfig_cmd/main_layers.cpp index b981f00f1e..50cbae543b 100644 --- a/vkconfig_cmd/main_layers.cpp +++ b/vkconfig_cmd/main_layers.cpp @@ -31,7 +31,7 @@ static int RunLayersOverride(const CommandLine& command_line) { Configuration configuration; const bool load_result = - configuration.Load(configurator.layers.selected_layers, command_line.layers_configuration_path.c_str()); + configuration.Load(command_line.layers_configuration_path.c_str(), configurator.layers.selected_layers); if (!load_result) { printf("\nFailed to load the layers configuration file...\n"); return -1; diff --git a/vkconfig_core/configuration.cpp b/vkconfig_core/configuration.cpp index 34f52a314e..94d5c0542d 100644 --- a/vkconfig_core/configuration.cpp +++ b/vkconfig_core/configuration.cpp @@ -54,7 +54,30 @@ Configuration Configuration::CreateDisabled(const std::vector& available_ return result; } -bool Configuration::Load3_0(const std::vector& available_layers, const QJsonObject& json_root_object) { +bool Configuration::Load(const Path& full_path, const std::vector& available_layers) { + assert(!full_path.Empty()); + + this->parameters.clear(); + + QFile file(full_path.AbsolutePath().c_str()); + const bool result = file.open(QIODevice::ReadOnly | QIODevice::Text); + assert(result); + std::string json_text = file.readAll().toStdString(); + file.close(); + + QJsonParseError parse_error; + QJsonDocument json_doc = QJsonDocument::fromJson(json_text.c_str(), &parse_error); + + if (parse_error.error != QJsonParseError::NoError) { + return false; + } + + Version version(json_doc.object().value("file_format_version").toString().toStdString()); + if (version < (Version(3, 0, 0))) { + return false; // Unsupported version + } + + const QJsonObject& json_root_object = json_doc.object(); const QJsonValue& json_configuration_value = json_root_object.value("configuration"); if (json_configuration_value == QJsonValue::Undefined) { return false; // Not a configuration file @@ -114,15 +137,33 @@ bool Configuration::Load3_0(const std::vector& available_layers, const QJ parameter.key = ReadStringValue(json_layer_object, "name").c_str(); parameter.overridden_rank = ReadIntValue(json_layer_object, "rank"); parameter.control = GetLayerControl(ReadStringValue(json_layer_object, "control").c_str()); + const std::string& version = ReadStringValue(json_layer_object, "version"); + parameter.api_version = version == "latest" ? Version::VERSION_NULL : Version(version.c_str()); const QJsonValue& json_platform_value = json_layer_object.value("platforms"); if (json_platform_value != QJsonValue::Undefined) { parameter.platform_flags = GetPlatformFlags(ReadStringArray(json_layer_object, "platforms")); } - const Layer* layer = FindByKey(available_layers, parameter.key.c_str()); + const Layer* layer = nullptr; + for (std::size_t i = 0, n = available_layers.size(); i < n; ++i) { + const Layer& current_layer = available_layers[i]; + if (current_layer.key != parameter.key) { + continue; + } + + if (parameter.api_version == Version::VERSION_NULL) { + if (layer == nullptr) { + layer = ¤t_layer; + } else if (layer->api_version < current_layer.api_version) { + layer = ¤t_layer; + } + } else if (parameter.api_version == current_layer.api_version) { + layer = ¤t_layer; + } + } + if (layer != nullptr) { - parameter.api_version = layer->api_version; CollectDefaultSettingData(layer->settings, parameter.settings); } @@ -134,10 +175,14 @@ bool Configuration::Load3_0(const std::vector& available_layers, const QJ const SettingType setting_type = GetSettingType(ReadStringValue(json_setting_object, "type").c_str()); SettingData* setting_data = FindSetting(parameter.settings, setting_key.c_str()); - if (setting_data == nullptr) continue; + if (setting_data == nullptr) { + continue; + } // Configuration type and layer type are differents, use layer default value - if (setting_data->type != setting_type) continue; + if (setting_data->type != setting_type) { + continue; + } const bool result = setting_data->Load(json_setting_object); assert(result); @@ -149,33 +194,7 @@ bool Configuration::Load3_0(const std::vector& available_layers, const QJ return true; } -bool Configuration::Load(const std::vector& available_layers, const Path& full_path) { - assert(!full_path.Empty()); - - this->parameters.clear(); - - QFile file(full_path.AbsolutePath().c_str()); - const bool result = file.open(QIODevice::ReadOnly | QIODevice::Text); - assert(result); - std::string json_text = file.readAll().toStdString(); - file.close(); - - QJsonParseError parse_error; - QJsonDocument json_doc = QJsonDocument::fromJson(json_text.c_str(), &parse_error); - - if (parse_error.error != QJsonParseError::NoError) { - return false; - } - - Version version(json_doc.object().value("file_format_version").toString().toStdString()); - if (version < (Version(3, 0, 0))) { - return false; // Unsupported version - } - - return Load3_0(available_layers, json_doc.object()); -} - -bool Configuration::Save(const std::vector& available_layers, const Path& full_path, bool exporter) const { +bool Configuration::Save(const Path& full_path, bool exporter) const { assert(!full_path.Empty()); QJsonObject root; @@ -202,6 +221,8 @@ bool Configuration::Save(const std::vector& available_layers, const Path& json_layer.insert("name", parameter.key.c_str()); json_layer.insert("rank", parameter.overridden_rank); json_layer.insert("control", GetToken(parameter.control)); + json_layer.insert("version", + parameter.api_version == Version::VERSION_NULL ? "latest" : parameter.api_version.str().c_str()); SaveStringArray(json_layer, "platforms", GetPlatformTokens(parameter.platform_flags)); QJsonArray json_settings; @@ -265,6 +286,16 @@ bool Configuration::Save(const std::vector& available_layers, const Path& } } +Parameter* Configuration::Find(std::string parameter_key) { + for (std::size_t i = 0, n = this->parameters.size(); i < n; ++i) { + if (this->parameters[i].key == parameter_key) { + return &this->parameters[i]; + } + } + + return nullptr; +} + void Configuration::Reset(const std::vector& available_layers) { // Case 1: reset using built-in configuration files const std::vector& builtin_configuration_files = CollectFilePaths(":/configurations/"); @@ -272,7 +303,7 @@ void Configuration::Reset(const std::vector& available_layers) { const std::string& basename = builtin_configuration_files[i].Basename(); if (this->key == basename) { - const bool result = this->Load(available_layers, builtin_configuration_files[i]); + const bool result = this->Load(builtin_configuration_files[i], available_layers); assert(result); OrderParameter(this->parameters, available_layers); @@ -286,7 +317,7 @@ void Configuration::Reset(const std::vector& available_layers) { std::FILE* file = std::fopen(full_path.AbsolutePath().c_str(), "r"); if (file) { std::fclose(file); - const bool result = this->Load(available_layers, full_path); + const bool result = this->Load(full_path, available_layers); assert(result); OrderParameter(this->parameters, available_layers); diff --git a/vkconfig_core/configuration.h b/vkconfig_core/configuration.h index b52270d1fc..fe89c3c0e3 100644 --- a/vkconfig_core/configuration.h +++ b/vkconfig_core/configuration.h @@ -34,9 +34,10 @@ class Configuration { static Configuration CreateDisabled(const std::vector& available_layers); - bool Load(const std::vector& available_layers, const Path& full_path); - bool Save(const std::vector& available_layers, const Path& full_path, bool exporter = false) const; + bool Load(const Path& full_path, const std::vector& available_layers); + bool Save(const Path& full_path, bool exporter = false) const; bool HasOverride() const; + Parameter* Find(std::string parameter_key); void Reset(const std::vector& available_layers); @@ -53,9 +54,6 @@ class Configuration { std::vector user_defined_paths; bool IsBuiltIn() const; - - private: - bool Load3_0(const std::vector& available_layers, const QJsonObject& json_root_object); }; std::string MakeConfigurationName(const std::vector& configurations, const std::string& configuration_name); diff --git a/vkconfig_core/configuration_manager.cpp b/vkconfig_core/configuration_manager.cpp index 73e21715f8..f184f6da90 100644 --- a/vkconfig_core/configuration_manager.cpp +++ b/vkconfig_core/configuration_manager.cpp @@ -43,7 +43,7 @@ void ConfigurationManager::LoadDefaultConfigurations(const std::vector &a for (int i = 0, n = configuration_files.size(); i < n; ++i) { Configuration configuration; - const bool result = configuration.Load(available_layers, configuration_files[i]); + const bool result = configuration.Load(configuration_files[i], available_layers); assert(result); if (!IsPlatformSupported(configuration.platform_flags)) { @@ -90,7 +90,7 @@ void ConfigurationManager::LoadConfigurationsPath(const std::vector &avai const std::vector &configuration_files = CollectFilePaths(Get(Path::CONFIGS)); for (int i = 0, n = configuration_files.size(); i < n; ++i) { Configuration configuration; - const bool result = configuration.Load(available_layers, configuration_files[i]); + const bool result = configuration.Load(configuration_files[i], available_layers); if (!result) { continue; } @@ -108,12 +108,15 @@ void ConfigurationManager::LoadConfigurationsPath(const std::vector &avai } } -static Path MakeConfigurationPath(const std::string &key) { return (Get(Path::CONFIGS) + "/" + key + ".json").AbsolutePath(); } +static Path MakeConfigurationPath(const std::string &key) { + const Path &path = Get(Path::CONFIGS) + "/" + key + ".json"; + return path.AbsolutePath(); +} -void ConfigurationManager::SaveAllConfigurations(const std::vector &available_layers) { +void ConfigurationManager::SaveAllConfigurations() { for (std::size_t i = 0, n = available_configurations.size(); i < n; ++i) { const Path &path(MakeConfigurationPath(available_configurations[i].key)); - available_configurations[i].Save(available_layers, path); + available_configurations[i].Save(path); } } @@ -125,11 +128,11 @@ Configuration &ConfigurationManager::CreateConfiguration(const std::vectoravailable_configurations.push_back(configuration); @@ -221,7 +224,7 @@ std::string ConfigurationManager::ImportConfiguration(const std::vector & assert(!full_import_path.Empty()); Configuration configuration; - if (!configuration.Load(available_layers, full_import_path)) { + if (!configuration.Load(full_import_path, available_layers)) { QMessageBox msg; msg.setIcon(QMessageBox::Critical); msg.setWindowTitle("Import of Layers Configuration error"); @@ -246,7 +249,7 @@ void ConfigurationManager::ExportConfiguration(const std::vector &availab Configuration *configuration = FindByKey(available_configurations, configuration_name.c_str()); assert(configuration); - if (!configuration->Save(available_layers, full_export_path, true)) { + if (!configuration->Save(full_export_path, true)) { QMessageBox msg; msg.setIcon(QMessageBox::Critical); msg.setWindowTitle("Export of Layers Configuration error"); diff --git a/vkconfig_core/configuration_manager.h b/vkconfig_core/configuration_manager.h index 36c6023fe0..4ed37c4de8 100644 --- a/vkconfig_core/configuration_manager.h +++ b/vkconfig_core/configuration_manager.h @@ -33,7 +33,7 @@ class ConfigurationManager { void LoadAllConfigurations(const std::vector& available_layers); - void SaveAllConfigurations(const std::vector& available_layers); + void SaveAllConfigurations(); Configuration& CreateConfiguration(const std::vector& available_layers, const std::string& configuration_name, bool duplicate = false); diff --git a/vkconfig_core/configurations/3.0.0/API dump.json b/vkconfig_core/configurations/3.0.0/API dump.json index 7c8e698cf3..12d674bb9f 100644 --- a/vkconfig_core/configurations/3.0.0/API dump.json +++ b/vkconfig_core/configurations/3.0.0/API dump.json @@ -15,7 +15,8 @@ "rank": 0, "settings": [ ], - "control": "on" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurations/3.0.0/Crash Diagnostic.json b/vkconfig_core/configurations/3.0.0/Crash Diagnostic.json index 31ea3cccb5..9bbe834a54 100644 --- a/vkconfig_core/configurations/3.0.0/Crash Diagnostic.json +++ b/vkconfig_core/configurations/3.0.0/Crash Diagnostic.json @@ -87,7 +87,8 @@ "value": true } ], - "state": "OVERRIDDEN" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurations/3.0.0/Frame Capture.json b/vkconfig_core/configurations/3.0.0/Frame Capture.json index 02e75cda9d..f0503f0b5b 100644 --- a/vkconfig_core/configurations/3.0.0/Frame Capture.json +++ b/vkconfig_core/configurations/3.0.0/Frame Capture.json @@ -19,7 +19,8 @@ "value": "${VK_LOCAL}/gfxrecon_capture.gfxr" } ], - "control": "on" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurations/3.0.0/Portability.json b/vkconfig_core/configurations/3.0.0/Portability.json index c49e7ce96a..7c33d6a4e6 100644 --- a/vkconfig_core/configurations/3.0.0/Portability.json +++ b/vkconfig_core/configurations/3.0.0/Portability.json @@ -10,59 +10,13 @@ ], "description": "Check the Vulkan application is portable to Apple platforms", "layers": [ - { - "name": "VK_LAYER_LUNARG_api_dump", - "rank": -1, - "settings": [ - ], - "control": "off" - }, - { - "name": "VK_LAYER_LUNARG_gfxreconstruct", - "rank": -1, - "settings": [ - ], - "control": "off", - "platforms": [ - "WINDOWS", - "LINUX" - ] - }, - { - "name": "VK_LAYER_LUNARG_monitor", - "rank": -1, - "settings": [ - ], - "control": "off", - "platforms": [ - "WINDOWS", - "LINUX" - ] - }, - { - "name": "VK_LAYER_LUNARG_screenshot", - "rank": -1, - "settings": [ - ], - "control": "off", - "platforms": [ - "WINDOWS", - "LINUX" - ] - }, - { - "name": "VK_LAYER_KHRONOS_synchronization2", - "rank": -1, - "settings": [ - ], - "control": "off" - }, { "name": "VK_LAYER_KHRONOS_validation", "rank": 4, "settings": [ ], - "control": "on" + "control": "on", + "version": "latest" }, { "name": "VK_LAYER_KHRONOS_profiles", @@ -79,7 +33,8 @@ "value": "VP_LUNARG_desktop_baseline_2023" } ], - "control": "on" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurations/3.0.0/Synchronization.json b/vkconfig_core/configurations/3.0.0/Synchronization.json index 17abe0cc41..4e1795292e 100644 --- a/vkconfig_core/configurations/3.0.0/Synchronization.json +++ b/vkconfig_core/configurations/3.0.0/Synchronization.json @@ -90,7 +90,8 @@ "value": false } ], - "control": "on" + "control": "on", + "version": "latest" }, { "name": "VK_LAYER_KHRONOS_synchronization2", @@ -102,7 +103,8 @@ "value": false } ], - "control": "on" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurations/3.0.0/Validation.json b/vkconfig_core/configurations/3.0.0/Validation.json index ef745c2fdf..62d14c31ac 100644 --- a/vkconfig_core/configurations/3.0.0/Validation.json +++ b/vkconfig_core/configurations/3.0.0/Validation.json @@ -15,7 +15,8 @@ "rank": 0, "settings": [ ], - "control": "on" + "control": "on", + "version": "latest" } ] } diff --git a/vkconfig_core/configurator.cpp b/vkconfig_core/configurator.cpp index 282b05f500..9e39aeff1c 100644 --- a/vkconfig_core/configurator.cpp +++ b/vkconfig_core/configurator.cpp @@ -302,7 +302,7 @@ Configurator& Configurator::Get() { Configurator::Configurator() : environment(), layers(), configurations() {} Configurator::~Configurator() { - configurations.SaveAllConfigurations(layers.selected_layers); + this->configurations.SaveAllConfigurations(); this->Surrender(); } diff --git a/vkconfig_core/parameter.cpp b/vkconfig_core/parameter.cpp index 98387b5268..fd3ecc0657 100644 --- a/vkconfig_core/parameter.cpp +++ b/vkconfig_core/parameter.cpp @@ -228,13 +228,15 @@ std::vector GatherParameters(const std::vector& parameters const Layer& layer = available_layers[i]; // The layer is already in the layer tree - if (IsFound(parameters, layer.key.c_str())) continue; + if (IsFound(parameters, layer.key.c_str())) { + continue; + } Parameter parameter; parameter.key = layer.key; parameter.control = LAYER_CONTROL_AUTO; - parameter.api_version = layer.api_version; - CollectDefaultSettingData(layer.settings, parameter.settings); + // parameter.api_version = layer.api_version; + // CollectDefaultSettingData(layer.settings, parameter.settings); gathered_parameters.push_back(parameter); } diff --git a/vkconfig_core/parameter.h b/vkconfig_core/parameter.h index b8e3f5fbfa..ac291f8c83 100644 --- a/vkconfig_core/parameter.h +++ b/vkconfig_core/parameter.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. @@ -38,21 +38,18 @@ enum ParameterRank { struct Parameter { static const int NO_RANK = -1; - Parameter() : control(LAYER_CONTROL_AUTO), platform_flags(PLATFORM_DESKTOP_BIT), overridden_rank(NO_RANK) { assert(true); } + Parameter() : control(LAYER_CONTROL_AUTO) {} - Parameter(const std::string& key, const LayerControl control) - : key(key), control(LAYER_CONTROL_AUTO), platform_flags(PLATFORM_DESKTOP_BIT), overridden_rank(NO_RANK) { - assert(true); - } + Parameter(const std::string& key, const LayerControl control) : key(key), control(control) {} bool ApplyPresetSettings(const LayerPreset& preset); std::string key; - LayerControl control; - int platform_flags; + LayerControl control = LAYER_CONTROL_AUTO; + int platform_flags = PLATFORM_DESKTOP_BIT; SettingDataSet settings; - int overridden_rank; - Version api_version; + int overridden_rank = NO_RANK; + Version api_version = Version::VERSION_NULL; }; ParameterRank GetParameterOrdering(const std::vector& available_layers, const Parameter& parameter); diff --git a/vkconfig_core/path.cpp b/vkconfig_core/path.cpp index bdb8e6ed75..3b136a2064 100644 --- a/vkconfig_core/path.cpp +++ b/vkconfig_core/path.cpp @@ -232,7 +232,7 @@ static const Path GetHomePath() { } static const Path GetAppDataPath() { - static const char* TABLE[] = { + const char* TABLE[] = { "/AppData/Local/LunarG", // ENVIRONMENT_WIN32 "/.local/share/vulkan" // ENVIRONMENT_UNIX }; @@ -242,7 +242,7 @@ static const Path GetAppDataPath() { } static const Path GetInitPath() { - static const std::string TABLE[] = { + const std::string TABLE[] = { "/" + VKCONFIG_VERSION + "/vkconfig.json", // ENVIRONMENT_WIN32 "/lunarg-" + VKCONFIG_VERSION + "/vkconfig.json" // ENVIRONMENT_UNIX }; @@ -252,13 +252,14 @@ static const Path GetInitPath() { } static const Path GetConfigsPath() { - static const std::string TABLE[] = { + const std::string TABLE[] = { "/" + VKCONFIG_VERSION + "/configurations", // ENVIRONMENT_WIN32 "/lunarg-" + VKCONFIG_VERSION + "/configurations" // ENVIRONMENT_UNIX }; static_assert(std::size(TABLE) == ENVIRONMENT_COUNT); - Path path(GetAppDataPath().RelativePath() + TABLE[VKC_ENV]); + Path app_data_path = GetAppDataPath(); + Path path(app_data_path + TABLE[VKC_ENV]); if (!path.Exists()) { path.Create(); diff --git a/vkconfig_core/test/Configuration 3.0.0.json b/vkconfig_core/test/Configuration 3.0.0.json index 54590008bb..1198e73b97 100644 --- a/vkconfig_core/test/Configuration 3.0.0.json +++ b/vkconfig_core/test/Configuration 3.0.0.json @@ -13,6 +13,7 @@ { "name": "VK_LAYER_LUNARG_reference_1_2_1", "rank": 8, + "version": "latest", "settings": [ { "key": "enum_required_only", diff --git a/vkconfig_core/test/test_configuration.cpp b/vkconfig_core/test/test_configuration.cpp index 5c17110910..16e306deed 100644 --- a/vkconfig_core/test/test_configuration.cpp +++ b/vkconfig_core/test/test_configuration.cpp @@ -60,7 +60,7 @@ static bool operator!=(const std::vector& a, const std::vector(), ":/test/Configuration 3.0.0.json"); + const bool load_loaded = configuration_loaded.Load(":/test/Configuration 3.0.0.json", std::vector()); EXPECT_TRUE(load_loaded); EXPECT_EQ(1, configuration_loaded.parameters.size()); EXPECT_TRUE(!configuration_loaded.description.empty()); @@ -69,10 +69,10 @@ TEST(test_configuration, load_and_save) { EXPECT_TRUE(parameter != nullptr); EXPECT_EQ(LAYER_CONTROL_ON, parameter->control); - configuration_loaded.Save(std::vector(), "test_layer_1_2_1.json"); + configuration_loaded.Save("test_layer_1_2_1.json"); Configuration configuration_saved; - configuration_saved.Load(std::vector(), "test_layer_1_2_1.json"); + configuration_saved.Load("test_layer_1_2_1.json", std::vector()); EXPECT_EQ(configuration_loaded, configuration_saved); } diff --git a/vkconfig_core/test/test_configuration_built_in.cpp b/vkconfig_core/test/test_configuration_built_in.cpp index 60e91f5efc..ca3d0f7160 100644 --- a/vkconfig_core/test/test_configuration_built_in.cpp +++ b/vkconfig_core/test/test_configuration_built_in.cpp @@ -72,18 +72,18 @@ struct TestBuilin { Configuration Load(const char* configuration_name) { Configuration configuration_loaded; - const bool result = configuration_loaded.Load(layer_manager.selected_layers, - format(":/configurations/%s.json", configuration_name).c_str()); + const bool result = configuration_loaded.Load(format(":/configurations/%s.json", configuration_name).c_str(), + layer_manager.selected_layers); return result ? configuration_loaded : Configuration(); } Configuration Restore(const Configuration& configuration_loaded) { const std::string filename = format("test_%s_layers.json", configuration_loaded.key.c_str()); - const bool saved = configuration_loaded.Save(this->layer_manager.selected_layers, filename.c_str()); + const bool saved = configuration_loaded.Save(filename.c_str()); EXPECT_TRUE(saved); Configuration configuration_saved; - EXPECT_TRUE(configuration_saved.Load(this->layer_manager.selected_layers, filename.c_str())); + EXPECT_TRUE(configuration_saved.Load(filename.c_str(), this->layer_manager.selected_layers)); return configuration_saved; } @@ -113,7 +113,7 @@ TEST(test_built_in_load, sdk_layers_with_configuration) { { Configuration load_portability = test.Load("Portability"); - EXPECT_EQ(7, load_portability.Size()); + EXPECT_EQ(2, load_portability.Size()); Configuration save_portability = test.Restore(load_portability); EXPECT_EQ(save_portability, load_portability); } diff --git a/vkconfig_gui/configuration_layer_widget.cpp b/vkconfig_gui/configuration_layer_widget.cpp new file mode 100644 index 0000000000..b057d5b7fd --- /dev/null +++ b/vkconfig_gui/configuration_layer_widget.cpp @@ -0,0 +1,128 @@ +/* + * 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 "configuration_layer_widget.h" +#include "widget_setting.h" + +#include "../vkconfig_core/configurator.h" + +ConfigurationLayerWidget::ConfigurationLayerWidget(const std::vector &layers, const Parameter ¶meter) + : layer_name(parameter.key) { + // const bool is_implicit_layer = layers.empty() ? false : layers[0]->type == LAYER_TYPE_IMPLICIT; + + if (parameter.control != LAYER_CONTROL_APPLICATIONS && parameter.control != LAYER_CONTROL_UNORDERED) { + this->layer_version = new QComboBox(this); + this->layer_version->addItem("Latest"); + int version_index = 0; + + for (std::size_t i = 0, n = layers.size(); i < n; ++i) { + if (layers[i]->key != parameter.key) { + continue; + } + + if (layers[i]->api_version == parameter.api_version) { + this->layer_version->setToolTip(layers[i]->manifest_path.AbsolutePath().c_str()); + version_index = this->layer_version->count(); + } + + this->layer_version->addItem(layers[i]->api_version.str().c_str()); + } + this->layer_version->setCurrentIndex(version_index); + + // this->layer_version->setEnabled(layers.size() > 1); + this->connect(this->layer_version, SIGNAL(currentIndexChanged(int)), this, SLOT(on_layer_version_currentIndexChanged(int))); + // 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.control); + this->connect(this->layer_state, SIGNAL(currentIndexChanged(int)), this, SLOT(on_layer_state_currentIndexChanged(int))); + // this->layer_state->installEventFilter(this); + } + + std::string decorated_name = parameter.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.control == LAYER_CONTROL_OFF) { + return; + } + + 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)); + } + + // if (IsDLL32Bit(layer->manifest_path)) { + // decorated_name += " (32-bit)"; + //} + } + this->setText(decorated_name.c_str()); +} + +bool ConfigurationLayerWidget::eventFilter(QObject *target, QEvent *event) { + if (event->type() == QEvent::Wheel) { + return true; + } + + return false; +} + +void ConfigurationLayerWidget::resizeEvent(QResizeEvent *event) { + QSize size = event->size(); + + 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 version_button_rect = QRect(size.width() - width_state - width_version, 0, width_version, size.height()); + this->layer_version->setGeometry(version_button_rect); + } +} + +void ConfigurationLayerWidget::on_layer_version_currentIndexChanged(int index) { + assert(index >= 0); + const std::string &text = this->layer_version->itemText(index).toStdString(); + Version version = text == "latest" ? Version::VERSION_NULL : Version(text.c_str()); + + Configuration *configuration = Configurator::Get().GetActiveConfiguration(); + Parameter *parameter = configuration->Find(this->layer_name); + parameter->api_version = version; +} + +void ConfigurationLayerWidget::on_layer_state_currentIndexChanged(int index) { + assert(index >= 0); + const std::string &text = this->layer_state->itemText(index).toStdString(); + + Configuration *configuration = Configurator::Get().GetActiveConfiguration(); + Parameter *parameter = configuration->Find(this->layer_name); + parameter->control = GetLayerControl(text.c_str()); +} diff --git a/vkconfig_gui/configuration_layer_widget.h b/vkconfig_gui/configuration_layer_widget.h new file mode 100644 index 0000000000..091d868df2 --- /dev/null +++ b/vkconfig_gui/configuration_layer_widget.h @@ -0,0 +1,50 @@ +/* + * 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 + */ + +#pragma once + +#include "../vkconfig_core/parameter.h" +#include "../vkconfig_core/layer.h" + +#include +#include +#include +#include + +class ConfigurationLayerWidget : public QLabel { + Q_OBJECT + + public: + ConfigurationLayerWidget(const std::vector &layers, const Parameter ¶meter); + + protected: + bool eventFilter(QObject *target, QEvent *event); + void resizeEvent(QResizeEvent *event) override; + + public Q_SLOTS: + void on_layer_version_currentIndexChanged(int index); + void on_layer_state_currentIndexChanged(int index); + + private: + std::string layer_name; + + QComboBox *layer_version = nullptr; + QComboBox *layer_state = nullptr; +}; diff --git a/vkconfig_gui/mainwindow.cpp b/vkconfig_gui/mainwindow.cpp index 6b2a0bc9ce..9192e78fed 100644 --- a/vkconfig_gui/mainwindow.cpp +++ b/vkconfig_gui/mainwindow.cpp @@ -531,7 +531,7 @@ void MainWindow::AddLayerPathItem(const std::string &layer_path) { ui->tree_layers_paths->setItemWidget(item_state, layer_path_widget); } -void MainWindow::AddLayerItem(const Parameter ¶meter) { +void MainWindow::AddLayerItem(Parameter ¶meter) { assert(!parameter.key.empty()); std::vector &available_layers = Configurator::Get().layers.selected_layers; @@ -574,47 +574,10 @@ void MainWindow::AddLayerItem(const Parameter ¶meter) { layers.push_back(layer); } - LayerWidget *layer_widget = new LayerWidget(layers, parameter, ui->layers_tree, item_state); + ConfigurationLayerWidget *layer_widget = new ConfigurationLayerWidget(layers, parameter); item_state->widget = layer_widget; ui->layers_tree->setItemWidget(item_state, layer_widget); - - // item_state->setDisabled(layer == nullptr); - - // item_state->layer_state->addItem(is_implicit_layer ? "Implicitly On" : "Application-Controlled"); - // item_state->layer_state->addItem("Forced On"); - // item_state->layer_state->addItem("Forced Off"); - - /* - const QFontMetrics fm = ui->tree_layers_list->fontMetrics(); - const QSize combo_name_size = fm.size(Qt::TextSingleLine, parameter.key.c_str()) * 1.2; - item_state->setSizeHint(0, combo_name_size); - - const QSize combo_version_size = fm.size(Qt::TextSingleLine, layer->api_version.str().c_str()); - item_state->setSizeHint(1, combo_version_size); - - const QSize combo_state_size = fm.size(Qt::TextSingleLine, "Application-Controlled"); - item_state->setSizeHint(2, combo_state_size); - */ - // Add the top level item - - // Add a combo box. Default has gray background which looks hidious - // WidgetTreeFriendlyComboBox *widget_version = new WidgetTreeFriendlyComboBox(item_state); - // ui->tree_layers_list->setItemWidget(item_state, 1, widget_version); - - // widget_version->addItem(layer->api_version.str().c_str()); - - // WidgetTreeFriendlyComboBox *widget_state = new WidgetTreeFriendlyComboBox(item_state); - // ui->tree_layers_list->setItemWidget(item_state, 2, widget_state); - - /* - widget_state->addItem(is_implicit_layer ? "Implicitly On" : "Application-Controlled"); - widget_state->addItem("Forced On"); - widget_state->addItem("Forced Off"); - widget_state->setCurrentIndex(parameter.state); - - connect(widget_state, SIGNAL(selectionMade(QListWidgetItem *, int)), this, SLOT(layerUseChanged(QListWidgetItem *, int))); - */ } void MainWindow::UpdateUI() { @@ -1042,7 +1005,7 @@ void MainWindow::on_combo_box_applications_currentIndexChanged(int index) { Application &application = configurator.environment.GetApplication(index); ui->combo_box_applications->setToolTip(application.executable_path.AbsolutePath().c_str()); - ui->combo_box_mode->setCurrentIndex(application.configuration.GetMode()); + ui->combo_box_mode->setCurrentIndex(configurator.environment.GetActiveConfigurationInfo().GetMode()); } void MainWindow::on_check_box_per_application_toggled(bool checked) { @@ -1151,7 +1114,7 @@ void MainWindow::OnConfigurationItemChanged(QTreeWidgetItem *item, int column) { // Rename configuration ; Remove old configuration file ; change the name of the configuration configurator.configurations.RemoveConfigurationFile(old_name); configuration->key = configuration_item->configuration_name = new_name; - configurator.configurations.SaveAllConfigurations(configurator.layers.selected_layers); + configurator.configurations.SaveAllConfigurations(); configurator.environment.GetActiveConfigurationInfo().SetName(new_name); LoadConfigurationList(); diff --git a/vkconfig_gui/mainwindow.h b/vkconfig_gui/mainwindow.h index 199359323b..9b21e74993 100644 --- a/vkconfig_gui/mainwindow.h +++ b/vkconfig_gui/mainwindow.h @@ -22,12 +22,12 @@ #pragma once #include "settings_tree.h" +#include "configuration_layer_widget.h" #include "ui_mainwindow.h" #include #include -#include #include #include #include @@ -54,94 +54,6 @@ class ConfigurationListItem : public QTreeWidgetItem { ConfigurationListItem &operator=(const ConfigurationListItem &) = delete; }; -class LayerWidget : public QLabel { - Q_OBJECT - - public: - LayerWidget(const std::vector layers, const Parameter ¶meter, QListWidget *list, QListWidgetItem *item) - : item(item), layer_version(nullptr), layer_state(nullptr) { - const bool is_implicit_layer = layers.empty() ? false : layers[0]->type == LAYER_TYPE_IMPLICIT; - - 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.AbsolutePath().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.control); - 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.control == LAYER_CONTROL_OFF) { - return; - } - - 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)); - } - - // if (IsDLL32Bit(layer->manifest_path)) { - // decorated_name += " (32-bit)"; - //} - } - this->setText(decorated_name.c_str()); - - item->setSizeHint(QSize(0, ITEM_HEIGHT)); - - // list->addItem(item); - // list->setItemWidget(item, this); - } - - protected: - bool eventFilter(QObject *target, QEvent *event) { - if (event->type() == QEvent::Wheel) { - return true; - } - - return false; - } - - void resizeEvent(QResizeEvent *event) override { - QSize size = event->size(); - - 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 version_button_rect = QRect(size.width() - width_state - width_version, 0, width_version, size.height()); - this->layer_version->setGeometry(version_button_rect); - } - } - - public: - QListWidgetItem *item; - - private: - QComboBox *layer_version; - QComboBox *layer_state; -}; - class LayerPathWidget : public QLabel { Q_OBJECT @@ -247,7 +159,7 @@ class MainWindow : public QMainWindow { void ImportClicked(ConfigurationListItem *item); void AddLayerPathItem(const std::string &layer_path); - void AddLayerItem(const Parameter ¶meter); + void AddLayerItem(Parameter ¶meter); private slots: void trayActionRestore(); diff --git a/vkconfig_gui/mainwindow.ui b/vkconfig_gui/mainwindow.ui index 526cad18db..a5943de9d9 100644 --- a/vkconfig_gui/mainwindow.ui +++ b/vkconfig_gui/mainwindow.ui @@ -615,6 +615,9 @@ Qt::Vertical + + false + @@ -669,7 +672,7 @@ - Layers Configuration Mode: + Layers Mode: @@ -701,7 +704,7 @@ - Per-Application Configuration: + Per-Application: diff --git a/vkconfig_gui/vkconfig.pro b/vkconfig_gui/vkconfig.pro index 21c48e7ec7..c717a62471 100644 --- a/vkconfig_gui/vkconfig.pro +++ b/vkconfig_gui/vkconfig.pro @@ -73,6 +73,7 @@ SOURCES += \ ../vkconfig_core/version.cpp \ ../vkconfig_core/vulkan_info.cpp \ ../vkconfig_core/vulkan_util.cpp \ + configuration_layer_widget.cpp \ widget_preset.cpp \ widget_setting.cpp \ widget_setting_bool.cpp \ @@ -139,6 +140,7 @@ HEADERS += \ ../vkconfig_core/version.h \ ../vkconfig_core/vulkan_info.h \ ../vkconfig_core/vulkan_util.h \ + configuration_layer_widget.h \ widget_preset.h \ widget_setting.h \ widget_setting_bool.h \