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();
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<int>(&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<int>(&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<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_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<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->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<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,
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<Settings::GraphicsAPI>(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<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);
}

View File

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

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<width>454</width>
<height>579</height>
</rect>
</property>
@ -27,48 +27,79 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="graphics_api_label">
<property name="text">
<string>Graphics API</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="graphics_api_combo">
<item>
<widget class="QWidget" name="graphics_api_group" native="true">
<layout class="QHBoxLayout" name="graphics_api_group_2">
<property name="spacing">
<number>7</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</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">
<string>OpenGL</string>
<string>Graphics API</string>
</property>
</item>
<item>
<property name="text">
<string>OpenGLES</string>
</property>
</item>
<item>
<property name="text">
<string>Vulkan</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QComboBox" name="graphics_api_combo">
<item>
<property name="text">
<string>OpenGL</string>
</property>
</item>
<item>
<property name="text">
<string>OpenGLES</string>
</property>
</item>
<item>
<property name="text">
<string>Vulkan</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<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 class="QWidget" name="physical_device_group" native="true">
<layout class="QHBoxLayout" name="physical_device_group_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<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>
<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);
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() {

View File

@ -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);

View File

@ -447,7 +447,7 @@ struct Values {
// Renderer
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> dump_command_buffers{false, "dump_command_buffers"};
SwitchableSetting<bool> spirv_shader_gen{true, "spirv_shader_gen"};