mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-30 07:27:53 -05:00
yuzu: Implement Vulkan frontend
Adds a Qt and SDL2 frontend for Vulkan. It also finishes the missing bits on Vulkan initialization.
This commit is contained in:
@ -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);
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>474</height>
|
||||
<height>467</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -103,44 +103,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="reporting_services">
|
||||
<property name="text">
|
||||
<string>Enable Verbose Reporting Services</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>This will be reset automatically when yuzu closes.</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="quest_flag">
|
||||
<property name="text">
|
||||
<string>Kiosk (Quest) Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -167,6 +129,95 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enable_graphics_debugging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string>When checked, the graphics API enters in a slower debugging mode</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Graphics Debugging</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Dump</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="dump_decompressed_nso">
|
||||
<property name="whatsThis">
|
||||
<string>When checked, any NSO yuzu tries to load or patch will be copied decompressed to the yuzu/dump directory.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Decompressed NSOs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="dump_exefs">
|
||||
<property name="whatsThis">
|
||||
<string>When checked, any game that yuzu loads will have its ExeFS dumped to the yuzu/dump directory.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump ExeFS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="reporting_services">
|
||||
<property name="text">
|
||||
<string>Enable Verbose Reporting Services</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>This will be reset automatically when yuzu closes.</string>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="quest_flag">
|
||||
<property name="text">
|
||||
<string>Kiosk (Quest) Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -185,6 +236,19 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>toggle_gdbstub</tabstop>
|
||||
<tabstop>gdbport_spinbox</tabstop>
|
||||
<tabstop>log_filter_edit</tabstop>
|
||||
<tabstop>toggle_console</tabstop>
|
||||
<tabstop>open_log_button</tabstop>
|
||||
<tabstop>homebrew_args_edit</tabstop>
|
||||
<tabstop>enable_graphics_debugging</tabstop>
|
||||
<tabstop>dump_decompressed_nso</tabstop>
|
||||
<tabstop>dump_exefs</tabstop>
|
||||
<tabstop>reporting_services</tabstop>
|
||||
<tabstop>quest_flag</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
@ -3,6 +3,13 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QComboBox>
|
||||
#ifdef HAS_VULKAN
|
||||
#include <QVulkanInstance>
|
||||
#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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
[this] { UpdateDeviceComboBox(); });
|
||||
connect(ui->device, static_cast<void (QComboBox::*)(int)>(&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<int>(Settings::values.renderer_backend));
|
||||
ui->resolution_factor_combobox->setCurrentIndex(
|
||||
static_cast<int>(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<Resolution>(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<PFN_vkEnumeratePhysicalDevices>(
|
||||
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<VkPhysicalDevice> 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<PFN_vkGetPhysicalDeviceProperties>(
|
||||
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<Settings::RendererBackend>(ui->api->currentIndex());
|
||||
}
|
||||
|
@ -5,7 +5,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#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::ConfigureGraphics> ui;
|
||||
QColor bg_color;
|
||||
|
||||
std::vector<QString> vulkan_devices;
|
||||
u32 vulkan_device{};
|
||||
};
|
||||
|
@ -7,21 +7,69 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<height>321</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_1">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>API Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>API:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="api">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">OpenGL</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string notr="true">Vulkan</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Device:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="device"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Graphics</string>
|
||||
<string>Graphics Settings</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_disk_shader_cache">
|
||||
<property name="text">
|
||||
@ -29,13 +77,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_accurate_gpu_emulation">
|
||||
<property name="text">
|
||||
<string>Use accurate GPU emulation (slow)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_asynchronous_gpu_emulation">
|
||||
<property name="text">
|
||||
@ -43,6 +84,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_accurate_gpu_emulation">
|
||||
<property name="text">
|
||||
<string>Use accurate GPU emulation (slow)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="force_30fps_mode">
|
||||
<property name="text">
|
||||
@ -51,11 +99,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Internal Resolution</string>
|
||||
<string>Internal Resolution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -91,7 +139,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="bg_label">
|
||||
<property name="text">
|
||||
|
Reference in New Issue
Block a user