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...
This commit is contained in:
GPUCode
2023-03-12 00:06:17 +02:00
parent eb8b463ca8
commit 12a5265db1
6 changed files with 139 additions and 54 deletions

View File

@ -19,7 +19,6 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
DiscoverPhysicalDevices(); DiscoverPhysicalDevices();
SetupPerGameUI(); SetupPerGameUI();
SetConfiguration();
const bool not_running = !Core::System::GetInstance().IsPoweredOn(); const bool not_running = !Core::System::GetInstance().IsPoweredOn();
const bool hw_renderer_enabled = ui->toggle_hw_renderer->isChecked(); 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->toggle_disk_shader_cache->setEnabled(hw_renderer_enabled && not_running);
ui->physical_device_combo->setEnabled(not_running); ui->physical_device_combo->setEnabled(not_running);
ui->toggle_async_shaders->setEnabled(not_running); ui->toggle_async_shaders->setEnabled(not_running);
SetPhysicalDeviceComboVisibility(ui->graphics_api_combo->currentIndex()); ui->graphics_api_combo->setCurrentIndex(-1);
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureGraphics::SetPhysicalDeviceComboVisibility);
connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] { connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] {
const bool checked = ui->toggle_hw_renderer->isChecked(); 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. // TODO(B3N30): Hide this for macs with none Intel GPUs, too.
ui->toggle_separable_shader->setVisible(false); ui->toggle_separable_shader->setVisible(false);
#endif #endif
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureGraphics::SetPhysicalDeviceComboVisibility);
SetConfiguration();
} }
ConfigureGraphics::~ConfigureGraphics() = default; ConfigureGraphics::~ConfigureGraphics() = default;
void ConfigureGraphics::SetConfiguration() { 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<int>(Settings::values.physical_device.GetValue()));
ui->graphics_api_combo->setCurrentIndex(
static_cast<int>(Settings::values.graphics_api.GetValue()));
}
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer.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_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue());
ui->toggle_separable_shader->setChecked(Settings::values.separable_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_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue());
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.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->toggle_vsync_new->setChecked(Settings::values.use_vsync_new.GetValue());
ui->graphics_api_combo->setCurrentIndex(
static_cast<int>(Settings::values.graphics_api.GetValue()));
ui->physical_device_combo->setCurrentIndex(
static_cast<int>(Settings::values.physical_device.GetValue()));
ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue()); ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue());
ui->toggle_async_shaders->setChecked(Settings::values.async_shader_compilation.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_vsync_new->setEnabled(Settings::values.use_vsync_new.UsingGlobal());
ui->toggle_async_shaders->setEnabled( ui->toggle_async_shaders->setEnabled(
Settings::values.async_shader_compilation.UsingGlobal()); 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; return;
} }
ui->toggle_shader_jit->setVisible(false); ui->toggle_shader_jit->setVisible(false);
ConfigurationShared::SetColoredComboBox(
ui->graphics_api_combo, ui->graphics_api_group,
static_cast<u32>(Settings::values.graphics_api.GetValue(true)));
ConfigurationShared::SetColoredComboBox(
ui->physical_device_combo, ui->physical_device_group,
static_cast<u32>(Settings::values.physical_device.GetValue(true)));
ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer, ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer,
Settings::values.use_hw_renderer, use_hw_renderer); Settings::values.use_hw_renderer, use_hw_renderer);
ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader, ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader,
@ -159,23 +182,45 @@ void ConfigureGraphics::SetupPerGameUI() {
ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders, ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders,
Settings::values.async_shader_compilation, Settings::values.async_shader_compilation,
async_shader_compilation); async_shader_compilation);
ConfigurationShared::SetColoredTristate(ui->spirv_shader_gen, Settings::values.spirv_shader_gen,
spirv_shader_gen);
} }
void ConfigureGraphics::DiscoverPhysicalDevices() { void ConfigureGraphics::DiscoverPhysicalDevices() {
if (physical_devices_discovered) {
return;
}
Vulkan::Instance instance{}; Vulkan::Instance instance{};
const auto physical_devices = instance.GetPhysicalDevices(); const auto physical_devices = instance.GetPhysicalDevices();
ui->physical_device_combo->clear();
for (const vk::PhysicalDevice& physical_device : physical_devices) { for (const vk::PhysicalDevice& physical_device : physical_devices) {
const QString name = QString::fromLocal8Bit(physical_device.getProperties().deviceName); const QString name = QString::fromLocal8Bit(physical_device.getProperties().deviceName);
ui->physical_device_combo->addItem(name); ui->physical_device_combo->addItem(name);
} }
physical_devices_discovered = true;
} }
void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) {
const auto graphics_api = static_cast<Settings::GraphicsAPI>(index); bool is_visible{false};
const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan;
ui->physical_device_label->setVisible(is_visible); // When configuring per-game the physical device combo should be
ui->physical_device_combo->setVisible(is_visible); // 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<Settings::GraphicsAPI>(index);
is_visible = (using_global && global_graphics_api == Settings::GraphicsAPI::Vulkan) ||
graphics_api == Settings::GraphicsAPI::Vulkan;
} else {
const auto graphics_api = static_cast<Settings::GraphicsAPI>(index);
is_visible = graphics_api == Settings::GraphicsAPI::Vulkan;
}
ui->physical_device_group->setVisible(is_visible);
ui->spirv_shader_gen->setVisible(is_visible); ui->spirv_shader_gen->setVisible(is_visible);
} }

View File

@ -44,4 +44,5 @@ private:
ConfigurationShared::CheckState spirv_shader_gen; ConfigurationShared::CheckState spirv_shader_gen;
std::unique_ptr<Ui::ConfigureGraphics> ui; std::unique_ptr<Ui::ConfigureGraphics> ui;
QColor bg_color; QColor bg_color;
bool physical_devices_discovered = false;
}; };

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>454</width>
<height>579</height> <height>579</height>
</rect> </rect>
</property> </property>
@ -27,48 +27,79 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <widget class="QWidget" name="graphics_api_group" native="true">
<item> <layout class="QHBoxLayout" name="graphics_api_group_2">
<widget class="QLabel" name="graphics_api_label"> <property name="spacing">
<property name="text"> <number>7</number>
<string>Graphics API</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QComboBox" name="graphics_api_combo"> <number>0</number>
<item> </property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="graphics_api_label">
<property name="text"> <property name="text">
<string>OpenGL</string> <string>Graphics API</string>
</property> </property>
</item> </widget>
<item> </item>
<property name="text"> <item>
<string>OpenGLES</string> <widget class="QComboBox" name="graphics_api_combo">
</property> <item>
</item> <property name="text">
<item> <string>OpenGL</string>
<property name="text"> </property>
<string>Vulkan</string> </item>
</property> <item>
</item> <property name="text">
</widget> <string>OpenGLES</string>
</item> </property>
</layout> </item>
<item>
<property name="text">
<string>Vulkan</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <widget class="QWidget" name="physical_device_group" native="true">
<item> <layout class="QHBoxLayout" name="physical_device_group_2">
<widget class="QLabel" name="physical_device_label"> <property name="leftMargin">
<property name="text"> <number>0</number>
<string>Physical device</string> </property>
</property> <property name="topMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="rightMargin">
<widget class="QComboBox" name="physical_device_combo"/> <number>0</number>
</item> </property>
</layout> <property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="physical_device_label">
<property name="text">
<string>Physical device</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="physical_device_combo"/>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="spirv_shader_gen"> <widget class="QCheckBox" name="spirv_shader_gen">

View File

@ -1109,6 +1109,9 @@ void GMainWindow::BootGame(const QString& filename) {
LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name); LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name);
Settings::LogSettings(); Settings::LogSettings();
// Update API indicator to reflect the per-game graphics API, if set.
UpdateAPIIndicator(false);
} }
// Save configurations // Save configurations
@ -1743,6 +1746,9 @@ void GMainWindow::OnPauseContinueGame() {
void GMainWindow::OnStopGame() { void GMainWindow::OnStopGame() {
ShutdownGame(); ShutdownGame();
Settings::RestoreGlobalState(false); Settings::RestoreGlobalState(false);
// If a per-game graphics API was set we should reset to the global option
UpdateAPIIndicator(false);
} }
void GMainWindow::OnLoadComplete() { void GMainWindow::OnLoadComplete() {

View File

@ -199,6 +199,8 @@ void RestoreGlobalState(bool is_powered_on) {
// Renderer // Renderer
values.use_hw_renderer.SetGlobal(true); values.use_hw_renderer.SetGlobal(true);
values.use_hw_shader.SetGlobal(true); values.use_hw_shader.SetGlobal(true);
values.graphics_api.SetGlobal(true);
values.physical_device.SetGlobal(true);
values.separable_shader.SetGlobal(true); values.separable_shader.SetGlobal(true);
values.async_shader_compilation.SetGlobal(true); values.async_shader_compilation.SetGlobal(true);
values.use_disk_shader_cache.SetGlobal(true); values.use_disk_shader_cache.SetGlobal(true);

View File

@ -447,7 +447,7 @@ struct Values {
// Renderer // Renderer
SwitchableSetting<GraphicsAPI> graphics_api{GraphicsAPI::OpenGL, "graphics_api"}; SwitchableSetting<GraphicsAPI> graphics_api{GraphicsAPI::OpenGL, "graphics_api"};
SwitchableSetting<u16> physical_device{0, "physical_device"}; SwitchableSetting<u32> physical_device{0, "physical_device"};
Setting<bool> renderer_debug{false, "renderer_debug"}; Setting<bool> renderer_debug{false, "renderer_debug"};
Setting<bool> dump_command_buffers{false, "dump_command_buffers"}; Setting<bool> dump_command_buffers{false, "dump_command_buffers"};
SwitchableSetting<bool> spirv_shader_gen{true, "spirv_shader_gen"}; SwitchableSetting<bool> spirv_shader_gen{true, "spirv_shader_gen"};