From f92cbc55018b5a3d98dd2093354f20c62ace5fda Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Tue, 21 Jan 2020 16:40:53 -0300 Subject: yuzu: Implement Vulkan frontend Adds a Qt and SDL2 frontend for Vulkan. It also finishes the missing bits on Vulkan initialization. --- src/yuzu/configuration/configure_debug.cpp | 3 + src/yuzu/configuration/configure_debug.ui | 116 ++++++++++++++++++++------ src/yuzu/configuration/configure_graphics.cpp | 94 +++++++++++++++++++++ src/yuzu/configuration/configure_graphics.h | 12 +++ src/yuzu/configuration/configure_graphics.ui | 72 +++++++++++++--- 5 files changed, 259 insertions(+), 38 deletions(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 90c1f9459..9631059c7 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp @@ -36,6 +36,8 @@ void ConfigureDebug::SetConfiguration() { ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); ui->reporting_services->setChecked(Settings::values.reporting_services); ui->quest_flag->setChecked(Settings::values.quest_flag); + ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); + ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); } void ConfigureDebug::ApplyConfiguration() { @@ -46,6 +48,7 @@ void ConfigureDebug::ApplyConfiguration() { Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); Settings::values.reporting_services = ui->reporting_services->isChecked(); Settings::values.quest_flag = ui->quest_flag->isChecked(); + Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); Debugger::ToggleConsole(); Log::Filter filter; filter.ParseFilterString(Settings::values.log_filter); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index ce49569bb..e028c4c80 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -7,7 +7,7 @@ 0 0 400 - 474 + 467 @@ -103,6 +103,80 @@ + + + + + + + Homebrew + + + + + + + + Arguments String + + + + + + + + + + + + + + + Graphics + + + + + + true + + + When checked, the graphics API enters in a slower debugging mode + + + Enable Graphics Debugging + + + + + + + + + + Dump + + + + + + When checked, any NSO yuzu tries to load or patch will be copied decompressed to the yuzu/dump directory. + + + Dump Decompressed NSOs + + + + + + + When checked, any game that yuzu loads will have its ExeFS dumped to the yuzu/dump directory. + + + Dump ExeFS + + + @@ -129,11 +203,11 @@ - + Advanced - + @@ -144,29 +218,6 @@ - - - - Homebrew - - - - - - - - Arguments String - - - - - - - - - - - @@ -185,6 +236,19 @@ + + toggle_gdbstub + gdbport_spinbox + log_filter_edit + toggle_console + open_log_button + homebrew_args_edit + enable_graphics_debugging + dump_decompressed_nso + dump_exefs + reporting_services + quest_flag + diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 2c9e322c9..f57a24e36 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -3,6 +3,13 @@ // Refer to the license.txt file included. #include +#include +#ifdef HAS_VULKAN +#include +#endif + +#include "common/common_types.h" +#include "common/logging/log.h" #include "core/core.h" #include "core/settings.h" #include "ui_configure_graphics.h" @@ -51,10 +58,18 @@ Resolution FromResolutionFactor(float factor) { ConfigureGraphics::ConfigureGraphics(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureGraphics) { + vulkan_device = Settings::values.vulkan_device; + RetrieveVulkanDevices(); + ui->setupUi(this); SetConfiguration(); + connect(ui->api, static_cast(&QComboBox::currentIndexChanged), this, + [this] { UpdateDeviceComboBox(); }); + connect(ui->device, static_cast(&QComboBox::activated), this, + [this](int device) { UpdateDeviceSelection(device); }); + connect(ui->bg_button, &QPushButton::clicked, this, [this] { const QColor new_bg_color = QColorDialog::getColor(bg_color); if (!new_bg_color.isValid()) { @@ -64,11 +79,22 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) }); } +void ConfigureGraphics::UpdateDeviceSelection(int device) { + if (device == -1) { + return; + } + if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) { + vulkan_device = device; + } +} + ConfigureGraphics::~ConfigureGraphics() = default; void ConfigureGraphics::SetConfiguration() { const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); + ui->api->setEnabled(runtime_lock); + ui->api->setCurrentIndex(static_cast(Settings::values.renderer_backend)); ui->resolution_factor_combobox->setCurrentIndex( static_cast(FromResolutionFactor(Settings::values.resolution_factor))); ui->use_disk_shader_cache->setEnabled(runtime_lock); @@ -80,9 +106,12 @@ void ConfigureGraphics::SetConfiguration() { ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode); UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue)); + UpdateDeviceComboBox(); } void ConfigureGraphics::ApplyConfiguration() { + Settings::values.renderer_backend = GetCurrentGraphicsBackend(); + Settings::values.vulkan_device = vulkan_device; Settings::values.resolution_factor = ToResolutionFactor(static_cast(ui->resolution_factor_combobox->currentIndex())); Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked(); @@ -116,3 +145,68 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) { const QIcon color_icon(pixmap); ui->bg_button->setIcon(color_icon); } + +void ConfigureGraphics::UpdateDeviceComboBox() { + ui->device->clear(); + + bool enabled = false; + switch (GetCurrentGraphicsBackend()) { + case Settings::RendererBackend::OpenGL: + ui->device->addItem(tr("OpenGL Graphics Device")); + enabled = false; + break; + case Settings::RendererBackend::Vulkan: + for (const auto device : vulkan_devices) { + ui->device->addItem(device); + } + ui->device->setCurrentIndex(vulkan_device); + enabled = !vulkan_devices.empty(); + break; + } + ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn()); +} + +void ConfigureGraphics::RetrieveVulkanDevices() { +#ifdef HAS_VULKAN + QVulkanInstance instance; + instance.setApiVersion(QVersionNumber(1, 1, 0)); + if (!instance.create()) { + LOG_INFO(Frontend, "Vulkan 1.1 not available"); + return; + } + const auto vkEnumeratePhysicalDevices{reinterpret_cast( + instance.getInstanceProcAddr("vkEnumeratePhysicalDevices"))}; + if (vkEnumeratePhysicalDevices == nullptr) { + LOG_INFO(Frontend, "Failed to get pointer to vkEnumeratePhysicalDevices"); + return; + } + u32 physical_device_count; + if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count, nullptr) != + VK_SUCCESS) { + LOG_INFO(Frontend, "Failed to get physical devices count"); + return; + } + std::vector physical_devices(physical_device_count); + if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count, + physical_devices.data()) != VK_SUCCESS) { + LOG_INFO(Frontend, "Failed to get physical devices"); + return; + } + + const auto vkGetPhysicalDeviceProperties{reinterpret_cast( + instance.getInstanceProcAddr("vkGetPhysicalDeviceProperties"))}; + if (vkGetPhysicalDeviceProperties == nullptr) { + LOG_INFO(Frontend, "Failed to get pointer to vkGetPhysicalDeviceProperties"); + return; + } + for (const auto physical_device : physical_devices) { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(physical_device, &properties); + vulkan_devices.push_back(QString::fromUtf8(properties.deviceName)); + } +#endif +} + +Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { + return static_cast(ui->api->currentIndex()); +} diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index fae28d98e..7e0596d9c 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h @@ -5,7 +5,10 @@ #pragma once #include +#include +#include #include +#include "core/settings.h" namespace Ui { class ConfigureGraphics; @@ -27,7 +30,16 @@ private: void SetConfiguration(); void UpdateBackgroundColorButton(QColor color); + void UpdateDeviceComboBox(); + void UpdateDeviceSelection(int device); + + void RetrieveVulkanDevices(); + + Settings::RendererBackend GetCurrentGraphicsBackend() const; std::unique_ptr ui; QColor bg_color; + + std::vector vulkan_devices; + u32 vulkan_device{}; }; diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 0309ee300..e24372204 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -7,21 +7,69 @@ 0 0 400 - 300 + 321 Form - + - + + + + + API Settings + + + + + + + + API: + + + + + + + + OpenGL + + + + + Vulkan + + + + + + + + + + + + Device: + + + + + + + + + + + - Graphics + Graphics Settings - + @@ -30,16 +78,16 @@ - + - Use accurate GPU emulation (slow) + Use asynchronous GPU emulation - + - Use asynchronous GPU emulation + Use accurate GPU emulation (slow) @@ -51,11 +99,11 @@ - + - Internal Resolution + Internal Resolution: @@ -91,7 +139,7 @@ - + -- cgit v1.2.3