citra_qt: Add vulkan options to the GUI
This commit is contained in:
parent
a67bfe544d
commit
6b51afaf1f
14 changed files with 256 additions and 24 deletions
|
@ -185,6 +185,8 @@ add_executable(citra-qt
|
||||||
util/spinbox.h
|
util/spinbox.h
|
||||||
util/util.cpp
|
util/util.cpp
|
||||||
util/util.h
|
util/util.h
|
||||||
|
util/vk_device_info.cpp
|
||||||
|
util/vk_device_info.h
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB COMPAT_LIST
|
file(GLOB COMPAT_LIST
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "citra_qt/configuration/configuration_shared.h"
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_debug.h"
|
#include "citra_qt/configuration/configure_debug.h"
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_configure_debug.h"
|
#include "ui_configure_debug.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
|
||||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||||
// so we can just convert from the sliders range (0 - 79) to the expected
|
// so we can just convert from the sliders range (0 - 79) to the expected
|
||||||
|
@ -34,8 +36,39 @@ ConfigureDebug::ConfigureDebug(bool is_powered_on_, QWidget* parent)
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(ui->toggle_renderer_debug, &QCheckBox::clicked, this, [this](bool checked) {
|
||||||
|
if (checked && Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::Vulkan) {
|
||||||
|
try {
|
||||||
|
Vulkan::Instance debug_inst{true};
|
||||||
|
} catch (vk::LayerNotPresentError&) {
|
||||||
|
ui->toggle_renderer_debug->toggle();
|
||||||
|
QMessageBox::warning(this, tr("Validation layer not available"),
|
||||||
|
tr("Unable to enable debug renderer because the layer "
|
||||||
|
"<strong>VK_LAYER_KHRONOS_validation</strong> is missing. "
|
||||||
|
"Please install the Vulkan SDK or the appropriate package "
|
||||||
|
"of your distribution"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->toggle_dump_command_buffers, &QCheckBox::clicked, this, [this](bool checked) {
|
||||||
|
if (checked && Settings::values.graphics_api.GetValue() == Settings::GraphicsAPI::Vulkan) {
|
||||||
|
try {
|
||||||
|
Vulkan::Instance debug_inst{false, true};
|
||||||
|
} catch (vk::LayerNotPresentError&) {
|
||||||
|
ui->toggle_dump_command_buffers->toggle();
|
||||||
|
QMessageBox::warning(this, tr("Command buffer dumping not available"),
|
||||||
|
tr("Unable to enable command buffer dumping because the layer "
|
||||||
|
"<strong>VK_LAYER_LUNARG_api_dump</strong> is missing. "
|
||||||
|
"Please install the Vulkan SDK or the appropriate package "
|
||||||
|
"of your distribution"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
|
ui->toggle_cpu_jit->setEnabled(!is_powered_on);
|
||||||
ui->toggle_renderer_debug->setEnabled(!is_powered_on);
|
ui->toggle_renderer_debug->setEnabled(!is_powered_on);
|
||||||
|
ui->toggle_dump_command_buffers->setEnabled(!is_powered_on);
|
||||||
|
|
||||||
// Set a minimum width for the label to prevent the slider from changing size.
|
// Set a minimum width for the label to prevent the slider from changing size.
|
||||||
// This scales across DPIs. (This value should be enough for "xxx%")
|
// This scales across DPIs. (This value should be enough for "xxx%")
|
||||||
|
@ -62,6 +95,7 @@ void ConfigureDebug::SetConfiguration() {
|
||||||
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
||||||
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
||||||
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
|
ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue());
|
||||||
|
ui->toggle_dump_command_buffers->setChecked(Settings::values.dump_command_buffers.GetValue());
|
||||||
|
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
||||||
|
@ -92,6 +126,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||||
Common::Log::SetGlobalFilter(filter);
|
Common::Log::SetGlobalFilter(filter);
|
||||||
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
||||||
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
|
Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked();
|
||||||
|
Settings::values.dump_command_buffers = ui->toggle_dump_command_buffers->isChecked();
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>523</width>
|
<width>523</width>
|
||||||
<height>447</height>
|
<height>458</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -112,16 +112,6 @@
|
||||||
<string>CPU</string>
|
<string>CPU</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="toggle_cpu_jit">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string><html><head/><body><p>Enables the use of the ARM JIT compiler for emulating the 3DS CPUs. Don't disable unless for debugging purposes</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable CPU JIT</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QWidget" name="clock_speed_widget" native="true">
|
<widget class="QWidget" name="clock_speed_widget" native="true">
|
||||||
<layout class="QHBoxLayout" name="clock_speed_layout">
|
<layout class="QHBoxLayout" name="clock_speed_layout">
|
||||||
|
@ -202,6 +192,16 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="toggle_cpu_jit">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Enables the use of the ARM JIT compiler for emulating the 3DS CPUs. Don't disable unless for debugging purposes</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable CPU JIT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="toggle_renderer_debug">
|
<widget class="QCheckBox" name="toggle_renderer_debug">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -209,6 +209,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="toggle_dump_command_buffers">
|
||||||
|
<property name="text">
|
||||||
|
<string>Dump command buffers</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -23,14 +23,14 @@
|
||||||
#include "ui_configure.h"
|
#include "ui_configure.h"
|
||||||
|
|
||||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_,
|
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, Core::System& system_,
|
||||||
bool enable_web_config)
|
std::span<const QString> physical_devices, bool enable_web_config)
|
||||||
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_},
|
: QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_},
|
||||||
system{system_}, is_powered_on{system.IsPoweredOn()},
|
system{system_}, is_powered_on{system.IsPoweredOn()},
|
||||||
general_tab{std::make_unique<ConfigureGeneral>(this)},
|
general_tab{std::make_unique<ConfigureGeneral>(this)},
|
||||||
system_tab{std::make_unique<ConfigureSystem>(system, this)},
|
system_tab{std::make_unique<ConfigureSystem>(system, this)},
|
||||||
input_tab{std::make_unique<ConfigureInput>(this)},
|
input_tab{std::make_unique<ConfigureInput>(this)},
|
||||||
hotkeys_tab{std::make_unique<ConfigureHotkeys>(this)},
|
hotkeys_tab{std::make_unique<ConfigureHotkeys>(this)},
|
||||||
graphics_tab{std::make_unique<ConfigureGraphics>(is_powered_on, this)},
|
graphics_tab{std::make_unique<ConfigureGraphics>(physical_devices, is_powered_on, this)},
|
||||||
enhancements_tab{std::make_unique<ConfigureEnhancements>(this)},
|
enhancements_tab{std::make_unique<ConfigureEnhancements>(this)},
|
||||||
audio_tab{std::make_unique<ConfigureAudio>(is_powered_on, this)},
|
audio_tab{std::make_unique<ConfigureAudio>(is_powered_on, this)},
|
||||||
camera_tab{std::make_unique<ConfigureCamera>(this)},
|
camera_tab{std::make_unique<ConfigureCamera>(this)},
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
class HotkeyRegistry;
|
class HotkeyRegistry;
|
||||||
|
|
||||||
|
@ -35,6 +37,7 @@ class ConfigureDialog : public QDialog {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, Core::System& system,
|
explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, Core::System& system,
|
||||||
|
std::span<const QString> physical_devices,
|
||||||
bool enable_web_config = true);
|
bool enable_web_config = true);
|
||||||
~ConfigureDialog() override;
|
~ConfigureDialog() override;
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,32 @@
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_configure_graphics.h"
|
#include "ui_configure_graphics.h"
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(bool is_powered_on, QWidget* parent)
|
ConfigureGraphics::ConfigureGraphics(std::span<const QString> physical_devices, bool is_powered_on,
|
||||||
|
QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
SetupPerGameUI();
|
||||||
|
|
||||||
|
for (const QString& name : physical_devices) {
|
||||||
|
ui->physical_device_combo->addItem(name);
|
||||||
|
}
|
||||||
|
|
||||||
ui->toggle_vsync_new->setEnabled(!is_powered_on);
|
ui->toggle_vsync_new->setEnabled(!is_powered_on);
|
||||||
ui->graphics_api_combo->setEnabled(!is_powered_on);
|
ui->graphics_api_combo->setEnabled(!is_powered_on);
|
||||||
|
ui->physical_device_combo->setEnabled(!is_powered_on);
|
||||||
|
ui->toggle_async_shaders->setEnabled(!is_powered_on);
|
||||||
|
ui->toggle_async_present->setEnabled(!is_powered_on);
|
||||||
// Set the index to -1 to ensure the below lambda is called with setCurrentIndex
|
// Set the index to -1 to ensure the below lambda is called with setCurrentIndex
|
||||||
ui->graphics_api_combo->setCurrentIndex(-1);
|
ui->graphics_api_combo->setCurrentIndex(-1);
|
||||||
|
|
||||||
|
if (physical_devices.empty()) {
|
||||||
|
const u32 index = static_cast<u32>(Settings::GraphicsAPI::Vulkan);
|
||||||
|
ui->graphics_api_combo->removeItem(index);
|
||||||
|
ui->physical_device_combo->setVisible(false);
|
||||||
|
ui->spirv_shader_gen->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
[this](int index) {
|
[this](int index) {
|
||||||
const auto graphics_api =
|
const auto graphics_api =
|
||||||
|
@ -35,7 +52,9 @@ ConfigureGraphics::ConfigureGraphics(bool is_powered_on, QWidget* parent)
|
||||||
ui->toggle_disk_shader_cache->setEnabled(checked && enabled);
|
ui->toggle_disk_shader_cache->setEnabled(checked && enabled);
|
||||||
});
|
});
|
||||||
|
|
||||||
SetupPerGameUI();
|
connect(ui->graphics_api_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
|
&ConfigureGraphics::SetPhysicalDeviceComboVisibility);
|
||||||
|
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,15 +66,24 @@ void ConfigureGraphics::SetConfiguration() {
|
||||||
!Settings::values.graphics_api.UsingGlobal());
|
!Settings::values.graphics_api.UsingGlobal());
|
||||||
ConfigurationShared::SetPerGameSetting(ui->graphics_api_combo,
|
ConfigurationShared::SetPerGameSetting(ui->graphics_api_combo,
|
||||||
&Settings::values.graphics_api);
|
&Settings::values.graphics_api);
|
||||||
|
ConfigurationShared::SetHighlight(ui->physical_device_group,
|
||||||
|
!Settings::values.physical_device.UsingGlobal());
|
||||||
|
ConfigurationShared::SetPerGameSetting(ui->physical_device_combo,
|
||||||
|
&Settings::values.physical_device);
|
||||||
} else {
|
} else {
|
||||||
ui->graphics_api_combo->setCurrentIndex(
|
ui->graphics_api_combo->setCurrentIndex(
|
||||||
static_cast<int>(Settings::values.graphics_api.GetValue()));
|
static_cast<int>(Settings::values.graphics_api.GetValue()));
|
||||||
|
ui->physical_device_combo->setCurrentIndex(
|
||||||
|
static_cast<int>(Settings::values.physical_device.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_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->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue());
|
||||||
|
ui->toggle_async_shaders->setChecked(Settings::values.async_shader_compilation.GetValue());
|
||||||
|
ui->toggle_async_present->setChecked(Settings::values.async_presentation.GetValue());
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue());
|
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue());
|
||||||
|
@ -65,6 +93,14 @@ void ConfigureGraphics::SetConfiguration() {
|
||||||
void ConfigureGraphics::ApplyConfiguration() {
|
void ConfigureGraphics::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.graphics_api,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.graphics_api,
|
||||||
ui->graphics_api_combo);
|
ui->graphics_api_combo);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.physical_device,
|
||||||
|
ui->physical_device_combo);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_shader_compilation,
|
||||||
|
ui->toggle_async_shaders, async_shader_compilation);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_presentation,
|
||||||
|
ui->toggle_async_present, async_presentation);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.spirv_shader_gen,
|
||||||
|
ui->spirv_shader_gen, spirv_shader_gen);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader,
|
||||||
use_hw_shader);
|
use_hw_shader);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul,
|
||||||
|
@ -93,6 +129,11 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||||
Settings::values.use_disk_shader_cache.UsingGlobal());
|
Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||||
ui->toggle_vsync_new->setEnabled(ui->toggle_vsync_new->isEnabled() &&
|
ui->toggle_vsync_new->setEnabled(ui->toggle_vsync_new->isEnabled() &&
|
||||||
Settings::values.use_vsync_new.UsingGlobal());
|
Settings::values.use_vsync_new.UsingGlobal());
|
||||||
|
ui->toggle_async_shaders->setEnabled(
|
||||||
|
Settings::values.async_shader_compilation.UsingGlobal());
|
||||||
|
ui->toggle_async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
|
||||||
|
ui->graphics_api_combo->setEnabled(Settings::values.graphics_api.UsingGlobal());
|
||||||
|
ui->physical_device_combo->setEnabled(Settings::values.physical_device.UsingGlobal());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +143,10 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||||
ui->graphics_api_combo, ui->graphics_api_group,
|
ui->graphics_api_combo, ui->graphics_api_group,
|
||||||
static_cast<u32>(Settings::values.graphics_api.GetValue(true)));
|
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_shader, Settings::values.use_hw_shader,
|
ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader,
|
||||||
use_hw_shader);
|
use_hw_shader);
|
||||||
ConfigurationShared::SetColoredTristate(
|
ConfigurationShared::SetColoredTristate(
|
||||||
|
@ -111,4 +156,34 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||||
use_disk_shader_cache);
|
use_disk_shader_cache);
|
||||||
ConfigurationShared::SetColoredTristate(ui->toggle_vsync_new, Settings::values.use_vsync_new,
|
ConfigurationShared::SetColoredTristate(ui->toggle_vsync_new, Settings::values.use_vsync_new,
|
||||||
use_vsync_new);
|
use_vsync_new);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders,
|
||||||
|
Settings::values.async_shader_compilation,
|
||||||
|
async_shader_compilation);
|
||||||
|
ConfigurationShared::SetColoredTristate(
|
||||||
|
ui->toggle_async_present, Settings::values.async_presentation, async_presentation);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->spirv_shader_gen, Settings::values.spirv_shader_gen,
|
||||||
|
spirv_shader_gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) {
|
||||||
|
bool is_visible{};
|
||||||
|
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
|
#include <QString>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -19,7 +21,8 @@ class ConfigureGraphics : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGraphics(bool is_powered_on, QWidget* parent = nullptr);
|
explicit ConfigureGraphics(std::span<const QString> physical_devices, bool is_powered_on,
|
||||||
|
QWidget* parent = nullptr);
|
||||||
~ConfigureGraphics() override;
|
~ConfigureGraphics() override;
|
||||||
|
|
||||||
void ApplyConfiguration();
|
void ApplyConfiguration();
|
||||||
|
@ -30,11 +33,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupPerGameUI();
|
void SetupPerGameUI();
|
||||||
|
void SetPhysicalDeviceComboVisibility(int index);
|
||||||
|
|
||||||
ConfigurationShared::CheckState use_hw_shader;
|
ConfigurationShared::CheckState use_hw_shader;
|
||||||
ConfigurationShared::CheckState shaders_accurate_mul;
|
ConfigurationShared::CheckState shaders_accurate_mul;
|
||||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||||
ConfigurationShared::CheckState use_vsync_new;
|
ConfigurationShared::CheckState use_vsync_new;
|
||||||
|
ConfigurationShared::CheckState async_shader_compilation;
|
||||||
|
ConfigurationShared::CheckState async_presentation;
|
||||||
|
ConfigurationShared::CheckState spirv_shader_gen;
|
||||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||||
QColor bg_color;
|
QColor bg_color;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>443</height>
|
<height>509</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
|
@ -73,6 +73,41 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<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">
|
||||||
|
<property name="text">
|
||||||
|
<string>SPIR-V Shader Generation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -100,7 +135,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="toggle_hw_shader">
|
<widget class="QCheckBox" name="toggle_hw_shader">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Use OpenGL to accelerate shader emulation.</p><p>Requires a relatively powerful GPU for better performance.</p></body></html></string>
|
<string><html><head/><body><p>Use the selected graphics API to accelerate shader emulation.</p><p>Requires a relatively powerful GPU for better performance.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable Hardware Shader</string>
|
<string>Enable Hardware Shader</string>
|
||||||
|
@ -148,6 +183,26 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="toggle_async_shaders">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Compile shaders using background threads to avoid shader compilation stutter. Expect temporary graphical glitches</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Async Shader Compilation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="toggle_async_present">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p>Perform presentation on separate threads. Improves performance when using Vulkan in most games.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Enable Async Presentation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "ui_configure_per_game.h"
|
#include "ui_configure_per_game.h"
|
||||||
|
|
||||||
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
||||||
Core::System& system_)
|
std::span<const QString> physical_devices, Core::System& system_)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
||||||
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
||||||
const auto config_file_name = title_id == 0 ? std::string(FileUtil::GetFilename(filename))
|
const auto config_file_name = title_id == 0 ? std::string(FileUtil::GetFilename(filename))
|
||||||
|
@ -35,7 +35,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString
|
||||||
audio_tab = std::make_unique<ConfigureAudio>(is_powered_on, this);
|
audio_tab = std::make_unique<ConfigureAudio>(is_powered_on, this);
|
||||||
general_tab = std::make_unique<ConfigureGeneral>(this);
|
general_tab = std::make_unique<ConfigureGeneral>(this);
|
||||||
enhancements_tab = std::make_unique<ConfigureEnhancements>(this);
|
enhancements_tab = std::make_unique<ConfigureEnhancements>(this);
|
||||||
graphics_tab = std::make_unique<ConfigureGraphics>(is_powered_on, this);
|
graphics_tab = std::make_unique<ConfigureGraphics>(physical_devices, is_powered_on, this);
|
||||||
system_tab = std::make_unique<ConfigureSystem>(system, this);
|
system_tab = std::make_unique<ConfigureSystem>(system, this);
|
||||||
debug_tab = std::make_unique<ConfigureDebug>(is_powered_on, this);
|
debug_tab = std::make_unique<ConfigureDebug>(is_powered_on, this);
|
||||||
cheat_tab = std::make_unique<ConfigureCheats>(system, title_id, this);
|
cheat_tab = std::make_unique<ConfigureCheats>(system, title_id, this);
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -35,9 +37,8 @@ class ConfigurePerGame : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263
|
|
||||||
explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
||||||
Core::System& system_);
|
std::span<const QString> physical_devices, Core::System& system_);
|
||||||
~ConfigurePerGame() override;
|
~ConfigurePerGame() override;
|
||||||
|
|
||||||
/// Loads all button configurations to settings file
|
/// Loads all button configurations to settings file
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "citra_qt/updater/updater.h"
|
#include "citra_qt/updater/updater.h"
|
||||||
#include "citra_qt/util/clickable_label.h"
|
#include "citra_qt/util/clickable_label.h"
|
||||||
|
#include "citra_qt/util/vk_device_info.h"
|
||||||
#include "common/arch.h"
|
#include "common/arch.h"
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/detached_tasks.h"
|
#include "common/detached_tasks.h"
|
||||||
|
@ -263,6 +264,14 @@ GMainWindow::GMainWindow(Core::System& system_)
|
||||||
connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
|
connect(&mouse_hide_timer, &QTimer::timeout, this, &GMainWindow::HideMouseCursor);
|
||||||
connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity);
|
connect(ui->menubar, &QMenuBar::hovered, this, &GMainWindow::OnMouseActivity);
|
||||||
|
|
||||||
|
physical_devices = GetVulkanPhysicalDevices();
|
||||||
|
if (physical_devices.empty()) {
|
||||||
|
QMessageBox::warning(this, tr("No Suitable Vulkan Devices Detected"),
|
||||||
|
tr("Vulkan initialization failed during boot.<br/>"
|
||||||
|
"Your GPU may not support Vulkan 1.1, or you do not "
|
||||||
|
"have the latest graphics driver."));
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_QT_UPDATER
|
#if ENABLE_QT_UPDATER
|
||||||
if (UISettings::values.check_for_update_on_start) {
|
if (UISettings::values.check_for_update_on_start) {
|
||||||
CheckForUpdates();
|
CheckForUpdates();
|
||||||
|
@ -2010,7 +2019,7 @@ void GMainWindow::OnLoadState() {
|
||||||
void GMainWindow::OnConfigure() {
|
void GMainWindow::OnConfigure() {
|
||||||
game_list->SetDirectoryWatcherEnabled(false);
|
game_list->SetDirectoryWatcherEnabled(false);
|
||||||
Settings::SetConfiguringGlobal(true);
|
Settings::SetConfiguringGlobal(true);
|
||||||
ConfigureDialog configureDialog(this, hotkey_registry, system,
|
ConfigureDialog configureDialog(this, hotkey_registry, system, physical_devices,
|
||||||
!multiplayer_state->IsHostingPublicRoom());
|
!multiplayer_state->IsHostingPublicRoom());
|
||||||
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
||||||
&GMainWindow::OnLanguageChanged);
|
&GMainWindow::OnLanguageChanged);
|
||||||
|
@ -2766,7 +2775,7 @@ void GMainWindow::OnConfigurePerGame() {
|
||||||
|
|
||||||
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) {
|
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) {
|
||||||
Settings::SetConfiguringGlobal(false);
|
Settings::SetConfiguringGlobal(false);
|
||||||
ConfigurePerGame dialog(this, title_id, file_name, system);
|
ConfigurePerGame dialog(this, title_id, file_name, physical_devices, system);
|
||||||
const auto result = dialog.exec();
|
const auto result = dialog.exec();
|
||||||
|
|
||||||
if (result != QDialog::Accepted) {
|
if (result != QDialog::Accepted) {
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QString>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include "citra_qt/compatibility_list.h"
|
#include "citra_qt/compatibility_list.h"
|
||||||
|
@ -326,6 +328,8 @@ private:
|
||||||
// Whether game was paused due to stopping video dumping
|
// Whether game was paused due to stopping video dumping
|
||||||
bool game_paused_for_dumping = false;
|
bool game_paused_for_dumping = false;
|
||||||
|
|
||||||
|
std::vector<QString> physical_devices;
|
||||||
|
|
||||||
// Debugger panes
|
// Debugger panes
|
||||||
ProfilerWidget* profilerWidget;
|
ProfilerWidget* profilerWidget;
|
||||||
MicroProfileDialog* microProfileDialog;
|
MicroProfileDialog* microProfileDialog;
|
||||||
|
|
23
src/citra_qt/util/vk_device_info.cpp
Normal file
23
src/citra_qt/util/vk_device_info.cpp
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2023 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "citra_qt/util/vk_device_info.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
|
||||||
|
std::vector<QString> GetVulkanPhysicalDevices() {
|
||||||
|
std::vector<QString> result;
|
||||||
|
try {
|
||||||
|
Vulkan::Instance instance{};
|
||||||
|
const auto physical_devices = instance.GetPhysicalDevices();
|
||||||
|
|
||||||
|
for (const vk::PhysicalDevice physical_device : physical_devices) {
|
||||||
|
const QString name = QString::fromLocal8Bit(physical_device.getProperties().deviceName);
|
||||||
|
result.push_back(name);
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
LOG_ERROR(Frontend, "Error occured while querying for physical devices.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
11
src/citra_qt/util/vk_device_info.h
Normal file
11
src/citra_qt/util/vk_device_info.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2023 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/// Returns a list of all available vulkan GPUs.
|
||||||
|
std::vector<QString> GetVulkanPhysicalDevices();
|
Loading…
Reference in a new issue