From 12a5265db13c59fae4e23cef59ec17e459e05d80 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 12 Mar 2023 00:06:17 +0200 Subject: [PATCH] citra_qt: Fix per-game graphics api option * This was a pain to implement due to the sheer amount of combinations. I hope there aren't any bugs... --- .../configuration/configure_graphics.cpp | 73 +++++++++--- .../configuration/configure_graphics.h | 1 + .../configuration/configure_graphics.ui | 109 +++++++++++------- src/citra_qt/main.cpp | 6 + src/common/settings.cpp | 2 + src/common/settings.h | 2 +- 6 files changed, 139 insertions(+), 54 deletions(-) diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index 6c16dc7e0..7376adcff 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -19,7 +19,6 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) DiscoverPhysicalDevices(); SetupPerGameUI(); - SetConfiguration(); const bool not_running = !Core::System::GetInstance().IsPoweredOn(); const bool hw_renderer_enabled = ui->toggle_hw_renderer->isChecked(); @@ -30,10 +29,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) ui->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running); ui->physical_device_combo->setEnabled(not_running); ui->toggle_async_shaders->setEnabled(not_running); - SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex()); - - connect(ui->graphics_api_combo, qOverload(&QComboBox::currentIndexChanged), this, - &ConfigureGraphics::SetPhysicalDeviceComboVisibility); + ui->graphics_api_combo->setCurrentIndex(-1); connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] { const bool checked = ui->toggle_hw_renderer->isChecked(); @@ -72,21 +68,38 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) // TODO(B3N30): Hide this for macs with none Intel GPUs, too. ui->toggle_separable_shader->setVisible(false); #endif + + connect(ui->graphics_api_combo, qOverload(&QComboBox::currentIndexChanged), this, + &ConfigureGraphics::SetPhysicalDeviceComboVisibility); + + SetConfiguration(); } ConfigureGraphics::~ConfigureGraphics() = default; void ConfigureGraphics::SetConfiguration() { + if (!Settings::IsConfiguringGlobal()) { + ConfigurationShared::SetHighlight(ui->physical_device_group, + !Settings::values.physical_device.UsingGlobal()); + ConfigurationShared::SetPerGameSetting(ui->physical_device_combo, + &Settings::values.physical_device); + ConfigurationShared::SetHighlight(ui->graphics_api_group, + !Settings::values.graphics_api.UsingGlobal()); + ConfigurationShared::SetPerGameSetting(ui->graphics_api_combo, + &Settings::values.graphics_api); + } else { + ui->physical_device_combo->setCurrentIndex( + static_cast(Settings::values.physical_device.GetValue())); + ui->graphics_api_combo->setCurrentIndex( + static_cast(Settings::values.graphics_api.GetValue())); + } + ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer.GetValue()); ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue()); ui->toggle_separable_shader->setChecked(Settings::values.separable_shader.GetValue()); ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue()); ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue()); ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new.GetValue()); - ui->graphics_api_combo->setCurrentIndex( - static_cast(Settings::values.graphics_api.GetValue())); - ui->physical_device_combo->setCurrentIndex( - static_cast(Settings::values.physical_device.GetValue())); ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue()); ui->toggle_async_shaders->setChecked(Settings::values.async_shader_compilation.GetValue()); @@ -138,11 +151,21 @@ void ConfigureGraphics::SetupPerGameUI() { ui->toggle_vsync_new->setEnabled(Settings::values.use_vsync_new.UsingGlobal()); ui->toggle_async_shaders->setEnabled( Settings::values.async_shader_compilation.UsingGlobal()); + ui->graphics_api_combo->setEnabled(Settings::values.graphics_api.UsingGlobal()); + ui->physical_device_combo->setEnabled(Settings::values.physical_device.UsingGlobal()); return; } ui->toggle_shader_jit->setVisible(false); + ConfigurationShared::SetColoredComboBox( + ui->graphics_api_combo, ui->graphics_api_group, + static_cast(Settings::values.graphics_api.GetValue(true))); + + ConfigurationShared::SetColoredComboBox( + ui->physical_device_combo, ui->physical_device_group, + static_cast(Settings::values.physical_device.GetValue(true))); + ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer, Settings::values.use_hw_renderer, use_hw_renderer); ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader, @@ -159,23 +182,45 @@ void ConfigureGraphics::SetupPerGameUI() { ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders, Settings::values.async_shader_compilation, async_shader_compilation); + ConfigurationShared::SetColoredTristate(ui->spirv_shader_gen, Settings::values.spirv_shader_gen, + spirv_shader_gen); } void ConfigureGraphics::DiscoverPhysicalDevices() { + if (physical_devices_discovered) { + return; + } + Vulkan::Instance instance{}; const auto physical_devices = instance.GetPhysicalDevices(); - ui->physical_device_combo->clear(); for (const vk::PhysicalDevice& physical_device : physical_devices) { const QString name = QString::fromLocal8Bit(physical_device.getProperties().deviceName); ui->physical_device_combo->addItem(name); } + + physical_devices_discovered = true; } void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { - const auto graphics_api = static_cast(index); - const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan; - ui->physical_device_label->setVisible(is_visible); - ui->physical_device_combo->setVisible(is_visible); + bool is_visible{false}; + + // When configuring per-game the physical device combo should be + // shown either when the global api is used and that is vulkan or + // vulkan is set as the per-game api. + if (!Settings::IsConfiguringGlobal()) { + const auto global_graphics_api = Settings::values.graphics_api.GetValue(true); + const bool using_global = index == 0; + if (!using_global) { + index -= ConfigurationShared::USE_GLOBAL_OFFSET; + } + const auto graphics_api = static_cast(index); + is_visible = (using_global && global_graphics_api == Settings::GraphicsAPI::Vulkan) || + graphics_api == Settings::GraphicsAPI::Vulkan; + } else { + const auto graphics_api = static_cast(index); + is_visible = graphics_api == Settings::GraphicsAPI::Vulkan; + } + ui->physical_device_group->setVisible(is_visible); ui->spirv_shader_gen->setVisible(is_visible); } diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 3853eb16d..e1f5c3b01 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -44,4 +44,5 @@ private: ConfigurationShared::CheckState spirv_shader_gen; std::unique_ptr ui; QColor bg_color; + bool physical_devices_discovered = false; }; diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index c1b99d027..94b1aad14 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -6,7 +6,7 @@ 0 0 - 400 + 454 579 @@ -27,48 +27,79 @@ - - - - - Graphics API - - - - - - + + + + 7 + + + 0 + + + 0 + + + 0 + + + 0 + + + - OpenGL + Graphics API - - - - OpenGLES - - - - - Vulkan - - - - - + + + + + + + OpenGL + + + + + OpenGLES + + + + + Vulkan + + + + + + - - - - - Physical device - - - - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Physical device + + + + + + + + diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index c4b981f30..ee7d21ba1 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -1109,6 +1109,9 @@ void GMainWindow::BootGame(const QString& filename) { LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name); Settings::LogSettings(); + + // Update API indicator to reflect the per-game graphics API, if set. + UpdateAPIIndicator(false); } // Save configurations @@ -1743,6 +1746,9 @@ void GMainWindow::OnPauseContinueGame() { void GMainWindow::OnStopGame() { ShutdownGame(); Settings::RestoreGlobalState(false); + + // If a per-game graphics API was set we should reset to the global option + UpdateAPIIndicator(false); } void GMainWindow::OnLoadComplete() { diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 9a88b2ebf..701bf4cfe 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -199,6 +199,8 @@ void RestoreGlobalState(bool is_powered_on) { // Renderer values.use_hw_renderer.SetGlobal(true); values.use_hw_shader.SetGlobal(true); + values.graphics_api.SetGlobal(true); + values.physical_device.SetGlobal(true); values.separable_shader.SetGlobal(true); values.async_shader_compilation.SetGlobal(true); values.use_disk_shader_cache.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 6279a4878..45609cb6b 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -447,7 +447,7 @@ struct Values { // Renderer SwitchableSetting graphics_api{GraphicsAPI::OpenGL, "graphics_api"}; - SwitchableSetting physical_device{0, "physical_device"}; + SwitchableSetting physical_device{0, "physical_device"}; Setting renderer_debug{false, "renderer_debug"}; Setting dump_command_buffers{false, "dump_command_buffers"}; SwitchableSetting spirv_shader_gen{true, "spirv_shader_gen"};