mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-04-01 17:08:31 -04:00
fix/feat: Introduce CAS & Add Dynamic Slider Viewing for Toggled WAF's, and remove Android ASTC visibility on PC
This commit is contained in:
@@ -31,6 +31,12 @@
|
|||||||
#include <qgridlayout.h>
|
#include <qgridlayout.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include "citron/configuration/configuration_shared.h"
|
||||||
|
#include "citron/configuration/configure_graphics.h"
|
||||||
|
#include "citron/configuration/shared_widget.h"
|
||||||
|
#include "citron/qt_common.h"
|
||||||
|
#include "citron/uisettings.h"
|
||||||
|
#include "citron/vk_device_info.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
@@ -38,12 +44,6 @@
|
|||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_graphics.h"
|
#include "ui_configure_graphics.h"
|
||||||
#include "citron/configuration/configuration_shared.h"
|
|
||||||
#include "citron/configuration/configure_graphics.h"
|
|
||||||
#include "citron/configuration/shared_widget.h"
|
|
||||||
#include "citron/qt_common.h"
|
|
||||||
#include "citron/uisettings.h"
|
|
||||||
#include "citron/vk_device_info.h"
|
|
||||||
|
|
||||||
static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR,
|
static const std::vector<VkPresentModeKHR> default_present_modes{VK_PRESENT_MODE_IMMEDIATE_KHR,
|
||||||
VK_PRESENT_MODE_FIFO_KHR};
|
VK_PRESENT_MODE_FIFO_KHR};
|
||||||
@@ -276,6 +276,14 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||||||
return builder.BuildWidget(
|
return builder.BuildWidget(
|
||||||
setting, apply_funcs, ConfigurationShared::RequestType::ReverseSlider, true,
|
setting, apply_funcs, ConfigurationShared::RequestType::ReverseSlider, true,
|
||||||
0.5f, nullptr, tr("%", "FSR sharpening percentage (e.g. 50%)"));
|
0.5f, nullptr, tr("%", "FSR sharpening percentage (e.g. 50%)"));
|
||||||
|
} else if (setting->Id() == Settings::values.cas_sharpening_slider.Id()) {
|
||||||
|
// CAS needs a 0.5 multiplier to show 0-100% (actually 0.0-0.5 internally if we
|
||||||
|
// follow FSR) Wait, CAS slider is 0-100 in settings.h. FSR is 0-200 internally?
|
||||||
|
// Actually FSR slider is 0-200 in settings.h.
|
||||||
|
// Let's check settings.h for CAS slider again.
|
||||||
|
return builder.BuildWidget(setting, apply_funcs,
|
||||||
|
ConfigurationShared::RequestType::Slider, true, 1.0f,
|
||||||
|
nullptr, tr("%"));
|
||||||
} else {
|
} else {
|
||||||
return builder.BuildWidget(setting, apply_funcs);
|
return builder.BuildWidget(setting, apply_funcs);
|
||||||
}
|
}
|
||||||
@@ -289,9 +297,20 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store reference to the FSR sharpness widget for later use
|
|
||||||
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) {
|
||||||
fsr_sharpness_widget = widget;
|
fsr_sharpness_widget = widget;
|
||||||
|
} else if (setting->Id() == Settings::values.cas_sharpening_slider.Id()) {
|
||||||
|
cas_sharpness_widget = widget;
|
||||||
|
} else if (setting->Id() == Settings::values.lanczos_quality.Id()) {
|
||||||
|
lq_widget = widget;
|
||||||
|
} else if (setting->Id() == Settings::values.crt_scanline_strength.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_curvature.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_gamma.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_bloom.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_mask_type.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_brightness.Id() ||
|
||||||
|
setting->Id() == Settings::values.crt_alpha.Id()) {
|
||||||
|
crt_widgets.push_back(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting->Id() == Settings::values.renderer_backend.Id()) {
|
if (setting->Id() == Settings::values.renderer_backend.Id()) {
|
||||||
@@ -372,39 +391,61 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) {
|
|||||||
api_grid_layout->addWidget(widget);
|
api_grid_layout->addWidget(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up FSR sharpness slider conditional enabling
|
// Set up Scaling Filter conditional visibility for sliders
|
||||||
if (fsr_sharpness_widget) {
|
QComboBox* scaling_filter_combobox = nullptr;
|
||||||
// Create a function to update the enabled state based on scaling filter
|
for (const auto& [id, widget] : hold_graphics) {
|
||||||
auto update_fsr_sharpness_enabled = [this]() {
|
if (id == Settings::values.scaling_filter.Id()) {
|
||||||
if (fsr_sharpness_widget) {
|
scaling_filter_combobox = static_cast<ConfigurationShared::Widget*>(widget)->combobox;
|
||||||
const auto scaling_filter = Settings::values.scaling_filter.GetValue();
|
break;
|
||||||
const bool fsr2_selected = (scaling_filter == Settings::ScalingFilter::Fsr2);
|
}
|
||||||
fsr_sharpness_widget->setEnabled(!fsr2_selected);
|
}
|
||||||
|
|
||||||
// Grey out the widget when disabled
|
if (scaling_filter_combobox) {
|
||||||
|
// Create a function to update the enabled/visible state based on current UI selection
|
||||||
|
auto update_visibility = [this, scaling_filter_combobox, &builder]() {
|
||||||
|
const auto& translations = builder.ComboboxTranslations().at(
|
||||||
|
Settings::EnumMetadata<Settings::ScalingFilter>::Index());
|
||||||
|
const auto scaling_filter = static_cast<Settings::ScalingFilter>(
|
||||||
|
translations.at(scaling_filter_combobox->currentIndex()).first);
|
||||||
|
|
||||||
|
if (fsr_sharpness_widget) {
|
||||||
|
const bool fsr_selected = (scaling_filter == Settings::ScalingFilter::Fsr);
|
||||||
|
const bool fsr2_selected = (scaling_filter == Settings::ScalingFilter::Fsr2);
|
||||||
|
|
||||||
|
// Visible only if FSR 1 or FSR 2 is selected
|
||||||
|
fsr_sharpness_widget->setVisible(fsr_selected || fsr2_selected);
|
||||||
|
|
||||||
|
// FSR 2.0 doesn't use the FSR 1.0 sharpness slider but we allow it to be visible
|
||||||
|
// but disabled to show it's an FSR-related setting.
|
||||||
|
fsr_sharpness_widget->setEnabled(!fsr2_selected);
|
||||||
if (fsr2_selected) {
|
if (fsr2_selected) {
|
||||||
fsr_sharpness_widget->setStyleSheet(QStringLiteral("QWidget { color: gray; }"));
|
fsr_sharpness_widget->setStyleSheet(QStringLiteral("QWidget { color: gray; }"));
|
||||||
} else {
|
} else {
|
||||||
fsr_sharpness_widget->setStyleSheet(QStringLiteral(""));
|
fsr_sharpness_widget->setStyleSheet(QStringLiteral(""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cas_sharpness_widget) {
|
||||||
|
cas_sharpness_widget->setVisible(scaling_filter == Settings::ScalingFilter::Cas);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lq_widget) {
|
||||||
|
lq_widget->setVisible(scaling_filter == Settings::ScalingFilter::Lanczos);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool crt_selected = (scaling_filter == Settings::ScalingFilter::CRTEasyMode ||
|
||||||
|
scaling_filter == Settings::ScalingFilter::CRTRoyale);
|
||||||
|
for (auto* crt_widget : crt_widgets) {
|
||||||
|
crt_widget->setVisible(crt_selected);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initial state
|
// Initial state
|
||||||
update_fsr_sharpness_enabled();
|
update_visibility();
|
||||||
|
|
||||||
// Connect to scaling filter changes
|
// Connect to scaling filter changes (real-time update)
|
||||||
if (!Settings::IsConfiguringGlobal()) {
|
QObject::connect(scaling_filter_combobox, QOverload<int>::of(&QComboBox::activated),
|
||||||
// Find the scaling filter widget and connect to its changes
|
[update_visibility]() { update_visibility(); });
|
||||||
for (const auto& [id, widget] : hold_graphics) {
|
|
||||||
if (id == Settings::values.scaling_filter.Id()) {
|
|
||||||
auto* config_widget = static_cast<ConfigurationShared::Widget*>(widget);
|
|
||||||
QObject::connect(config_widget->combobox, QOverload<int>::of(&QComboBox::activated),
|
|
||||||
[update_fsr_sharpness_enabled]() { update_fsr_sharpness_enabled(); });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background color is too specific to build into the new system, so we manage it here
|
// Background color is too specific to build into the new system, so we manage it here
|
||||||
@@ -615,8 +656,10 @@ void ConfigureGraphics::SetTemplateStyleSheet(const QString& sheet) {
|
|||||||
// Replace all placeholders with the actual color values in #RRGGBB format
|
// Replace all placeholders with the actual color values in #RRGGBB format
|
||||||
// Use QStringLiteral() to satisfy Qt 6's explicit string constructor requirements
|
// Use QStringLiteral() to satisfy Qt 6's explicit string constructor requirements
|
||||||
final_style.replace(QStringLiteral("%%ACCENT_COLOR%%"), accent_color.name(QColor::HexRgb));
|
final_style.replace(QStringLiteral("%%ACCENT_COLOR%%"), accent_color.name(QColor::HexRgb));
|
||||||
final_style.replace(QStringLiteral("%%ACCENT_COLOR_HOVER%%"), accent_color_hover.name(QColor::HexRgb));
|
final_style.replace(QStringLiteral("%%ACCENT_COLOR_HOVER%%"),
|
||||||
final_style.replace(QStringLiteral("%%ACCENT_COLOR_PRESSED%%"), accent_color_pressed.name(QColor::HexRgb));
|
accent_color_hover.name(QColor::HexRgb));
|
||||||
|
final_style.replace(QStringLiteral("%%ACCENT_COLOR_PRESSED%%"),
|
||||||
|
accent_color_pressed.name(QColor::HexRgb));
|
||||||
|
|
||||||
// Apply the processed stylesheet to this widget and all its children (like checkboxes)
|
// Apply the processed stylesheet to this widget and all its children (like checkboxes)
|
||||||
this->setStyleSheet(final_style);
|
this->setStyleSheet(final_style);
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <qobjectdefs.h>
|
#include <qobjectdefs.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
#include "citron/configuration/configuration_shared.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
#include "configuration/shared_translation.h"
|
#include "configuration/shared_translation.h"
|
||||||
#include "vk_device_info.h"
|
#include "vk_device_info.h"
|
||||||
#include "citron/configuration/configuration_shared.h"
|
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QEvent;
|
class QEvent;
|
||||||
@@ -47,7 +47,8 @@ class ConfigureGraphics : public ConfigurationShared::Tab {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
// This property allows the main UI file to pass its stylesheet to this widget
|
// This property allows the main UI file to pass its stylesheet to this widget
|
||||||
Q_PROPERTY(QString templateStyleSheet READ GetTemplateStyleSheet WRITE SetTemplateStyleSheet NOTIFY TemplateStyleSheetChanged)
|
Q_PROPERTY(QString templateStyleSheet READ GetTemplateStyleSheet WRITE SetTemplateStyleSheet
|
||||||
|
NOTIFY TemplateStyleSheetChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigureGraphics(
|
explicit ConfigureGraphics(
|
||||||
@@ -125,6 +126,9 @@ private:
|
|||||||
QComboBox* aspect_ratio_combobox;
|
QComboBox* aspect_ratio_combobox;
|
||||||
QComboBox* resolution_combobox;
|
QComboBox* resolution_combobox;
|
||||||
QWidget* fsr_sharpness_widget;
|
QWidget* fsr_sharpness_widget;
|
||||||
|
QWidget* cas_sharpness_widget;
|
||||||
|
QWidget* lq_widget;
|
||||||
|
std::vector<QWidget*> crt_widgets;
|
||||||
|
|
||||||
// This variable will hold the raw stylesheet string
|
// This variable will hold the raw stylesheet string
|
||||||
QString m_template_style_sheet;
|
QString m_template_style_sheet;
|
||||||
|
|||||||
@@ -2,21 +2,22 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "citron/configuration/configure_graphics_advanced.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
|
#include "citron/configuration/configuration_shared.h"
|
||||||
|
#include "citron/configuration/configure_graphics_advanced.h"
|
||||||
|
#include "citron/configuration/shared_translation.h"
|
||||||
|
#include "citron/configuration/shared_widget.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "ui_configure_graphics_advanced.h"
|
#include "ui_configure_graphics_advanced.h"
|
||||||
#include "citron/configuration/configuration_shared.h"
|
|
||||||
#include "citron/configuration/shared_translation.h"
|
|
||||||
#include "citron/configuration/shared_widget.h"
|
|
||||||
|
|
||||||
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
|
ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
|
||||||
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
const Core::System& system_, std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_,
|
||||||
const ConfigurationShared::Builder& builder, QWidget* parent)
|
const ConfigurationShared::Builder& builder, QWidget* parent)
|
||||||
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} {
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@@ -36,27 +37,32 @@ void ConfigureGraphicsAdvanced::Setup(const ConfigurationShared::Builder& builde
|
|||||||
std::map<u32, QWidget*> hold{}; // A map will sort the data for us
|
std::map<u32, QWidget*> hold{}; // A map will sort the data for us
|
||||||
|
|
||||||
for (auto setting :
|
for (auto setting :
|
||||||
Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
|
Settings::values.linkage.by_category[Settings::Category::RendererAdvanced]) {
|
||||||
|
#ifndef ANDROID
|
||||||
|
if (setting->Id() == Settings::values.android_astc_mode.Id()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
|
||||||
|
|
||||||
if (widget == nullptr) {
|
if (widget == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (!widget->Valid()) {
|
|
||||||
widget->deleteLater();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hold.emplace(setting->Id(), widget);
|
|
||||||
|
|
||||||
// Keep track of enable_compute_pipelines so we can display it when needed
|
|
||||||
if (setting->Id() == Settings::values.enable_compute_pipelines.Id()) {
|
|
||||||
checkbox_enable_compute_pipelines = widget;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (const auto& [id, widget] : hold) {
|
if (!widget->Valid()) {
|
||||||
layout.addWidget(widget);
|
widget->deleteLater();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hold.emplace(setting->Id(), widget);
|
||||||
|
|
||||||
|
// Keep track of enable_compute_pipelines so we can display it when needed
|
||||||
|
if (setting->Id() == Settings::values.enable_compute_pipelines.Id()) {
|
||||||
|
checkbox_enable_compute_pipelines = widget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& [id, widget] : hold) {
|
||||||
|
layout.addWidget(widget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "citron/uisettings.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/settings_enums.h"
|
#include "common/settings_enums.h"
|
||||||
#include "common/settings_setting.h"
|
#include "common/settings_setting.h"
|
||||||
#include "common/time_zone.h"
|
#include "common/time_zone.h"
|
||||||
#include "citron/uisettings.h"
|
|
||||||
|
|
||||||
namespace ConfigurationShared {
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
@@ -130,30 +130,42 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
|||||||
"much more VRAM and bandwidth.\n"
|
"much more VRAM and bandwidth.\n"
|
||||||
"Options lower than 1X can cause rendering issues."));
|
"Options lower than 1X can cause rendering issues."));
|
||||||
INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral());
|
INSERT(Settings, scaling_filter, tr("Window Adapting Filter:"), QStringLiteral());
|
||||||
INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness:"),
|
INSERT(Settings, fsr_sharpening_slider, tr("FSR Sharpness"),
|
||||||
tr("Determines how sharpened the image will look while using FSR's dynamic contrast."));
|
tr("Determines how sharpened the image will look while using FSR's dynamic contrast."));
|
||||||
INSERT(Settings, lanczos_quality, tr("Lanczos Quality:"), tr("The quality of the Lanczos filter. Higher is sharper but more expensive."));
|
INSERT(Settings, cas_sharpening_slider, tr("CAS Sharpness"),
|
||||||
|
tr("Determines the level of sharpening applied by the Contrast Adaptive Sharpening "
|
||||||
|
"(CAS) filter."));
|
||||||
|
INSERT(Settings, lanczos_quality, tr("Lanczos Quality:"),
|
||||||
|
tr("The quality of the Lanczos filter. Higher is sharper but more expensive."));
|
||||||
INSERT(Settings, fsr2_quality_mode, tr("FSR 2.0 Quality Mode:"),
|
INSERT(Settings, fsr2_quality_mode, tr("FSR 2.0 Quality Mode:"),
|
||||||
tr("Selects the quality mode for FSR 2.0 upscaling. Quality provides better image quality, Performance provides better performance."));
|
tr("Selects the quality mode for FSR 2.0 upscaling. Quality provides better image "
|
||||||
|
"quality, Performance provides better performance."));
|
||||||
INSERT(Settings, crt_scanline_strength, tr("CRT Scanline Strength:"),
|
INSERT(Settings, crt_scanline_strength, tr("CRT Scanline Strength:"),
|
||||||
tr("Controls the intensity of scanlines. Higher values create more pronounced horizontal lines."));
|
tr("Controls the intensity of scanlines. Higher values create more pronounced "
|
||||||
|
"horizontal lines."));
|
||||||
INSERT(Settings, crt_curvature, tr("CRT Curvature:"),
|
INSERT(Settings, crt_curvature, tr("CRT Curvature:"),
|
||||||
tr("Applies barrel distortion to simulate the curved screen of a CRT monitor."));
|
tr("Applies barrel distortion to simulate the curved screen of a CRT monitor."));
|
||||||
INSERT(Settings, crt_gamma, tr("CRT Gamma:"),
|
INSERT(Settings, crt_gamma, tr("CRT Gamma:"),
|
||||||
tr("Adjusts the gamma correction curve. Higher values brighten the image, lower values darken it."));
|
tr("Adjusts the gamma correction curve. Higher values brighten the image, lower values "
|
||||||
|
"darken it."));
|
||||||
INSERT(Settings, crt_bloom, tr("CRT Bloom:"),
|
INSERT(Settings, crt_bloom, tr("CRT Bloom:"),
|
||||||
tr("Controls the glow effect around bright areas, simulating phosphor persistence."));
|
tr("Controls the glow effect around bright areas, simulating phosphor persistence."));
|
||||||
INSERT(Settings, crt_mask_type, tr("CRT Mask Type:"),
|
INSERT(Settings, crt_mask_type, tr("CRT Mask Type:"),
|
||||||
tr("Selects the phosphor mask pattern: None, Aperture Grille (vertical stripes), or Shadow Mask (triangular pattern)."));
|
tr("Selects the phosphor mask pattern: None, Aperture Grille (vertical stripes), or "
|
||||||
|
"Shadow Mask (triangular pattern)."));
|
||||||
INSERT(Settings, crt_brightness, tr("CRT Brightness:"),
|
INSERT(Settings, crt_brightness, tr("CRT Brightness:"),
|
||||||
tr("Adjusts overall brightness of the CRT effect. Use to compensate for darkening from other effects."));
|
tr("Adjusts overall brightness of the CRT effect. Use to compensate for darkening from "
|
||||||
|
"other effects."));
|
||||||
INSERT(Settings, crt_alpha, tr("CRT Alpha:"),
|
INSERT(Settings, crt_alpha, tr("CRT Alpha:"),
|
||||||
tr("Controls transparency of the CRT effect. Lower values make the effect more transparent."));
|
tr("Controls transparency of the CRT effect. Lower values make the effect more "
|
||||||
|
"transparent."));
|
||||||
|
|
||||||
INSERT(Settings, frame_skipping, tr("Frame Skipping:"),
|
INSERT(Settings, frame_skipping, tr("Frame Skipping:"),
|
||||||
tr("Skips frames to maintain performance when the system cannot keep up with the target frame rate."));
|
tr("Skips frames to maintain performance when the system cannot keep up with the target "
|
||||||
INSERT(Settings, frame_skipping_mode, tr("Frame Skipping Mode:"),
|
"frame rate."));
|
||||||
tr("Adaptive mode skips frames based on performance, while Fixed mode skips a specific number of frames."));
|
INSERT(Settings, frame_skipping_mode, tr("Frame Skipping Mode:"),
|
||||||
|
tr("Adaptive mode skips frames based on performance, while Fixed mode skips a specific "
|
||||||
|
"number of frames."));
|
||||||
INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"),
|
INSERT(Settings, anti_aliasing, tr("Anti-Aliasing Method:"),
|
||||||
tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a "
|
tr("The anti-aliasing method to use.\nSMAA offers the best quality.\nFXAA has a "
|
||||||
"lower performance impact and can produce a better and more stable picture under "
|
"lower performance impact and can produce a better and more stable picture under "
|
||||||
@@ -202,10 +214,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
|||||||
INSERT(Settings, vram_limit_mb, tr("VRAM Limit (MB):"),
|
INSERT(Settings, vram_limit_mb, tr("VRAM Limit (MB):"),
|
||||||
tr("Sets the maximum VRAM usage limit in megabytes. Set to 0 for auto-detection "
|
tr("Sets the maximum VRAM usage limit in megabytes. Set to 0 for auto-detection "
|
||||||
"(80% of available VRAM). Recommended: 6144 for 8GB GPUs, 4096 for 6GB GPUs."));
|
"(80% of available VRAM). Recommended: 6144 for 8GB GPUs, 4096 for 6GB GPUs."));
|
||||||
INSERT(Settings, gc_aggressiveness, tr("GC Aggressiveness:"),
|
INSERT(
|
||||||
tr("Controls how aggressively the emulator evicts unused textures and buffers from VRAM.\n"
|
Settings, gc_aggressiveness, tr("GC Aggressiveness:"),
|
||||||
"Off: Disable automatic cleanup (not recommended, may cause crashes).\n"
|
tr("Controls how aggressively the emulator evicts unused textures and buffers from VRAM.\n"
|
||||||
"Light: Gentle cleanup, keeps more textures cached (recommended)."));
|
"Off: Disable automatic cleanup (not recommended, may cause crashes).\n"
|
||||||
|
"Light: Gentle cleanup, keeps more textures cached (recommended)."));
|
||||||
INSERT(Settings, texture_eviction_frames, tr("Texture Eviction Frames:"),
|
INSERT(Settings, texture_eviction_frames, tr("Texture Eviction Frames:"),
|
||||||
tr("Number of frames a texture must be unused before it can be evicted. "
|
tr("Number of frames a texture must be unused before it can be evicted. "
|
||||||
"Lower values free VRAM faster but may cause more texture reloading."));
|
"Lower values free VRAM faster but may cause more texture reloading."));
|
||||||
@@ -271,16 +284,18 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
|||||||
"unlocked."));
|
"unlocked."));
|
||||||
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
|
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
|
||||||
tr("Improves rendering of transparency effects in specific games."));
|
tr("Improves rendering of transparency effects in specific games."));
|
||||||
INSERT(Settings, extended_dynamic_state, tr("Extended Dynamic State:"),
|
INSERT(
|
||||||
tr("Selects the level of Vulkan Extended Dynamic State support.\n"
|
Settings, extended_dynamic_state, tr("Extended Dynamic State:"),
|
||||||
"EDS3: Enables all Extended Dynamic State features (recommended).\n"
|
tr("Selects the level of Vulkan Extended Dynamic State support.\n"
|
||||||
"EDS2: Enables EDS1 and EDS2 features only.\n"
|
"EDS3: Enables all Extended Dynamic State features (recommended).\n"
|
||||||
"EDS1: Enables basic Extended Dynamic State features only.\n"
|
"EDS2: Enables EDS1 and EDS2 features only.\n"
|
||||||
"Disabled: Disables all Extended Dynamic State features (may reduce compatibility)."));
|
"EDS1: Enables basic Extended Dynamic State features only.\n"
|
||||||
INSERT(Settings, use_conditional_rendering, tr("Use conditional rendering"),
|
"Disabled: Disables all Extended Dynamic State features (may reduce compatibility)."));
|
||||||
tr("Enables conditional rendering based on query results.\n"
|
INSERT(
|
||||||
"Disabling this can fix flickering objects in some games but may impact performance.\n"
|
Settings, use_conditional_rendering, tr("Use conditional rendering"),
|
||||||
"Try disabling if you see objects appearing and disappearing rapidly."));
|
tr("Enables conditional rendering based on query results.\n"
|
||||||
|
"Disabling this can fix flickering objects in some games but may impact performance.\n"
|
||||||
|
"Try disabling if you see objects appearing and disappearing rapidly."));
|
||||||
|
|
||||||
// Renderer (Debug)
|
// Renderer (Debug)
|
||||||
|
|
||||||
@@ -477,6 +492,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
|
|||||||
PAIR(ScalingFilter, Fsr2, tr("AMD FidelityFX™️ Super Resolution 2.0")),
|
PAIR(ScalingFilter, Fsr2, tr("AMD FidelityFX™️ Super Resolution 2.0")),
|
||||||
PAIR(ScalingFilter, CRTEasyMode, tr("CRT EasyMode")),
|
PAIR(ScalingFilter, CRTEasyMode, tr("CRT EasyMode")),
|
||||||
PAIR(ScalingFilter, CRTRoyale, tr("CRT Royale")),
|
PAIR(ScalingFilter, CRTRoyale, tr("CRT Royale")),
|
||||||
|
PAIR(ScalingFilter, Cas, tr("CAS (Contrast Adaptive Sharpening)")),
|
||||||
}});
|
}});
|
||||||
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
translations->insert({Settings::EnumMetadata<Settings::AntiAliasing>::Index(),
|
||||||
{
|
{
|
||||||
@@ -493,16 +509,16 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
|
|||||||
PAIR(FSR2QualityMode, UltraPerformance, tr("Ultra Performance")),
|
PAIR(FSR2QualityMode, UltraPerformance, tr("Ultra Performance")),
|
||||||
}});
|
}});
|
||||||
|
|
||||||
translations->insert({Settings::EnumMetadata<Settings::FrameSkipping>::Index(),
|
translations->insert({Settings::EnumMetadata<Settings::FrameSkipping>::Index(),
|
||||||
{
|
{
|
||||||
PAIR(FrameSkipping, Disabled, tr("Disabled")),
|
PAIR(FrameSkipping, Disabled, tr("Disabled")),
|
||||||
PAIR(FrameSkipping, Enabled, tr("Enabled")),
|
PAIR(FrameSkipping, Enabled, tr("Enabled")),
|
||||||
}});
|
}});
|
||||||
translations->insert({Settings::EnumMetadata<Settings::FrameSkippingMode>::Index(),
|
translations->insert({Settings::EnumMetadata<Settings::FrameSkippingMode>::Index(),
|
||||||
{
|
{
|
||||||
PAIR(FrameSkippingMode, Adaptive, tr("Adaptive")),
|
PAIR(FrameSkippingMode, Adaptive, tr("Adaptive")),
|
||||||
PAIR(FrameSkippingMode, Fixed, tr("Fixed")),
|
PAIR(FrameSkippingMode, Fixed, tr("Fixed")),
|
||||||
}});
|
}});
|
||||||
translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
|
translations->insert({Settings::EnumMetadata<Settings::AspectRatio>::Index(),
|
||||||
{
|
{
|
||||||
PAIR(AspectRatio, R16_9, tr("Default (16:9)")),
|
PAIR(AspectRatio, R16_9, tr("Default (16:9)")),
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map
|
|||||||
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
|
||||||
{Settings::ScalingFilter::Gaussian,
|
{Settings::ScalingFilter::Gaussian,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
|
||||||
{Settings::ScalingFilter::Lanczos, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Lanczos"))},
|
{Settings::ScalingFilter::Lanczos, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Lanczos"))},
|
||||||
{Settings::ScalingFilter::ScaleForce,
|
{Settings::ScalingFilter::ScaleForce,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
|
||||||
{Settings::ScalingFilter::ScaleFx,
|
{Settings::ScalingFilter::ScaleFx, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleFX"))},
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleFX"))},
|
|
||||||
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
|
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
|
||||||
{Settings::ScalingFilter::Fsr2, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR 2.0"))},
|
{Settings::ScalingFilter::Fsr2, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR 2.0"))},
|
||||||
{Settings::ScalingFilter::CRTEasyMode,
|
{Settings::ScalingFilter::CRTEasyMode,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "CRT EasyMode"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "CRT EasyMode"))},
|
||||||
{Settings::ScalingFilter::CRTRoyale,
|
{Settings::ScalingFilter::CRTRoyale,
|
||||||
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "CRT Royale"))},
|
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "CRT Royale"))},
|
||||||
|
{Settings::ScalingFilter::Cas, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "CAS"))},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
|
||||||
|
|||||||
@@ -5710,8 +5710,22 @@ void GMainWindow::UpdateAPIText() {
|
|||||||
void GMainWindow::UpdateFilterText() {
|
void GMainWindow::UpdateFilterText() {
|
||||||
const auto filter = Settings::values.scaling_filter.GetValue();
|
const auto filter = Settings::values.scaling_filter.GetValue();
|
||||||
const auto filter_text = ConfigurationShared::scaling_filter_texts_map.find(filter)->second;
|
const auto filter_text = ConfigurationShared::scaling_filter_texts_map.find(filter)->second;
|
||||||
filter_status_button->setText(filter == Settings::ScalingFilter::Fsr ? tr("FSR")
|
QString label;
|
||||||
: filter_text.toUpper());
|
switch (filter) {
|
||||||
|
case Settings::ScalingFilter::Fsr:
|
||||||
|
label = tr("FSR");
|
||||||
|
break;
|
||||||
|
case Settings::ScalingFilter::Fsr2:
|
||||||
|
label = tr("FSR2");
|
||||||
|
break;
|
||||||
|
case Settings::ScalingFilter::Cas:
|
||||||
|
label = tr("CAS");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
label = filter_text.toUpper();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
filter_status_button->setText(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::UpdateAAText() {
|
void GMainWindow::UpdateAAText() {
|
||||||
@@ -6512,7 +6526,6 @@ void GMainWindow::CheckForUpdatesAutomatically() {
|
|||||||
|
|
||||||
void GMainWindow::RegisterAutoloaderContents() {
|
void GMainWindow::RegisterAutoloaderContents() {
|
||||||
autoloader_provider->ClearAllEntries();
|
autoloader_provider->ClearAllEntries();
|
||||||
const auto& disabled_addons = Settings::values.disabled_addons;
|
|
||||||
|
|
||||||
const auto sdmc_path = Common::FS::GetCitronPath(Common::FS::CitronPath::SDMCDir);
|
const auto sdmc_path = Common::FS::GetCitronPath(Common::FS::CitronPath::SDMCDir);
|
||||||
const auto autoloader_root = sdmc_path / "autoloader";
|
const auto autoloader_root = sdmc_path / "autoloader";
|
||||||
@@ -6526,17 +6539,13 @@ void GMainWindow::RegisterAutoloaderContents() {
|
|||||||
if (!title_dir_entry.is_directory())
|
if (!title_dir_entry.is_directory())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u64 title_id_val = 0;
|
|
||||||
try {
|
try {
|
||||||
title_id_val = std::stoull(title_dir_entry.path().filename().string(), nullptr, 16);
|
[[maybe_unused]] auto val =
|
||||||
|
std::stoull(title_dir_entry.path().filename().string(), nullptr, 16);
|
||||||
} catch (const std::invalid_argument&) {
|
} catch (const std::invalid_argument&) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto it = disabled_addons.find(title_id_val);
|
|
||||||
const auto& disabled_for_game =
|
|
||||||
(it != disabled_addons.end()) ? it->second : std::vector<std::string>{};
|
|
||||||
|
|
||||||
const auto process_content_type = [&](const std::filesystem::path& content_path) {
|
const auto process_content_type = [&](const std::filesystem::path& content_path) {
|
||||||
if (!Common::FS::IsDir(content_path))
|
if (!Common::FS::IsDir(content_path))
|
||||||
return;
|
return;
|
||||||
@@ -6546,7 +6555,7 @@ void GMainWindow::RegisterAutoloaderContents() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const std::string mod_name = mod_dir_entry.path().filename().string();
|
const std::string mod_name = mod_dir_entry.path().filename().string();
|
||||||
// Citron: We do NOT skip disabled content here.
|
// We do NOT skip disabled content here.
|
||||||
// If we skip it here, it doesn't show up in the UI (Properties -> Add-ons),
|
// If we skip it here, it doesn't show up in the UI (Properties -> Add-ons),
|
||||||
// making it impossible for the user to re-enable it.
|
// making it impossible for the user to re-enable it.
|
||||||
// The PatchManager (core/file_sys/patch_manager.cpp) handles the actual enforcement
|
// The PatchManager (core/file_sys/patch_manager.cpp) handles the actual enforcement
|
||||||
|
|||||||
@@ -353,72 +353,47 @@ struct Values {
|
|||||||
Specialization::Percentage,
|
Specialization::Percentage,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
SwitchableSetting<int, true> cas_sharpening_slider{linkage,
|
||||||
|
50,
|
||||||
|
0,
|
||||||
|
100,
|
||||||
|
"cas_sharpening_slider",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Scalar |
|
||||||
|
Specialization::Percentage,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
|
||||||
// CRT Shader Settings (only active when CRT filter is selected)
|
// CRT Shader Settings (only active when CRT filter is selected)
|
||||||
SwitchableSetting<float, true> crt_scanline_strength{linkage,
|
SwitchableSetting<float, true> crt_scanline_strength{
|
||||||
1.0f, // 100/100 = 1.0 (range 0-200, actual 0.0-2.0)
|
linkage,
|
||||||
0.0f,
|
1.0f, // 100/100 = 1.0 (range 0-200, actual 0.0-2.0)
|
||||||
2.0f,
|
0.0f, 2.0f, "crt_scanline_strength", Category::Renderer, Specialization::Scalar,
|
||||||
"crt_scanline_strength",
|
true, true};
|
||||||
Category::Renderer,
|
SwitchableSetting<float, true> crt_curvature{
|
||||||
Specialization::Scalar,
|
linkage, 0.0f, 0.0f, 1.0f, "crt_curvature", Category::Renderer, Specialization::Scalar,
|
||||||
true,
|
true, true};
|
||||||
true};
|
SwitchableSetting<float, true> crt_gamma{
|
||||||
SwitchableSetting<float, true> crt_curvature{linkage,
|
linkage,
|
||||||
0.0f,
|
1.0f, // 100 maps to 1.0 (range 1-300, actual 1.0-3.0)
|
||||||
0.0f,
|
1.0f, 3.0f, "crt_gamma", Category::Renderer, Specialization::Scalar, true, true};
|
||||||
1.0f,
|
SwitchableSetting<float, true> crt_bloom{
|
||||||
"crt_curvature",
|
linkage,
|
||||||
Category::Renderer,
|
0.33f, // 33/100 = 0.33 (range 0-100, actual 0.0-1.0)
|
||||||
Specialization::Scalar,
|
0.0f, 1.0f, "crt_bloom", Category::Renderer, Specialization::Scalar, true, true};
|
||||||
true,
|
SwitchableSetting<int, true> crt_mask_type{
|
||||||
true};
|
linkage,
|
||||||
SwitchableSetting<float, true> crt_gamma{linkage,
|
1, // Already correct
|
||||||
1.0f, // 100 maps to 1.0 (range 1-300, actual 1.0-3.0)
|
0, 2, "crt_mask_type", Category::Renderer, Specialization::Scalar,
|
||||||
1.0f,
|
true, true}; // 0=none, 1=aperture, 2=shadow
|
||||||
3.0f,
|
SwitchableSetting<float, true> crt_brightness{
|
||||||
"crt_gamma",
|
linkage,
|
||||||
Category::Renderer,
|
1.0f, // Default brightness (1.0 = no change)
|
||||||
Specialization::Scalar,
|
0.0f, 2.0f, "crt_brightness", Category::Renderer, Specialization::Scalar, true, true};
|
||||||
true,
|
SwitchableSetting<float, true> crt_alpha{
|
||||||
true};
|
linkage,
|
||||||
SwitchableSetting<float, true> crt_bloom{linkage,
|
1.0f, // Default alpha (1.0 = fully opaque)
|
||||||
0.33f, // 33/100 = 0.33 (range 0-100, actual 0.0-1.0)
|
0.0f, 1.0f, "crt_alpha", Category::Renderer, Specialization::Scalar, true, true};
|
||||||
0.0f,
|
|
||||||
1.0f,
|
|
||||||
"crt_bloom",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Scalar,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
SwitchableSetting<int, true> crt_mask_type{linkage,
|
|
||||||
1, // Already correct
|
|
||||||
0,
|
|
||||||
2,
|
|
||||||
"crt_mask_type",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Scalar,
|
|
||||||
true,
|
|
||||||
true}; // 0=none, 1=aperture, 2=shadow
|
|
||||||
SwitchableSetting<float, true> crt_brightness{linkage,
|
|
||||||
1.0f, // Default brightness (1.0 = no change)
|
|
||||||
0.0f,
|
|
||||||
2.0f,
|
|
||||||
"crt_brightness",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Scalar,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
SwitchableSetting<float, true> crt_alpha{linkage,
|
|
||||||
1.0f, // Default alpha (1.0 = fully opaque)
|
|
||||||
0.0f,
|
|
||||||
1.0f,
|
|
||||||
"crt_alpha",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Scalar,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
|
|
||||||
SwitchableSetting<int, true> lanczos_quality{linkage,
|
SwitchableSetting<int, true> lanczos_quality{linkage,
|
||||||
3, // Default value
|
3, // Default value
|
||||||
@@ -430,37 +405,38 @@ struct Values {
|
|||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
SwitchableSetting<FSR2QualityMode, true> fsr2_quality_mode{linkage,
|
SwitchableSetting<FSR2QualityMode, true> fsr2_quality_mode{
|
||||||
FSR2QualityMode::Quality, // Quality by default
|
linkage,
|
||||||
FSR2QualityMode::Quality, // Min value
|
FSR2QualityMode::Quality, // Quality by default
|
||||||
FSR2QualityMode::UltraPerformance, // Max value
|
FSR2QualityMode::Quality, // Min value
|
||||||
"fsr2_quality_mode",
|
FSR2QualityMode::UltraPerformance, // Max value
|
||||||
Category::Renderer,
|
"fsr2_quality_mode",
|
||||||
Specialization::Default,
|
Category::Renderer,
|
||||||
true,
|
Specialization::Default,
|
||||||
true};
|
true,
|
||||||
|
true};
|
||||||
|
|
||||||
|
SwitchableSetting<FrameSkipping, true> frame_skipping{
|
||||||
|
linkage,
|
||||||
|
FrameSkipping::Disabled, // Disabled by default
|
||||||
|
FrameSkipping::Disabled,
|
||||||
|
FrameSkipping::Enabled,
|
||||||
|
"frame_skipping",
|
||||||
|
Category::Renderer,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
|
||||||
|
SwitchableSetting<FrameSkippingMode, true> frame_skipping_mode{
|
||||||
SwitchableSetting<FrameSkipping, true> frame_skipping{linkage,
|
linkage,
|
||||||
FrameSkipping::Disabled, // Disabled by default
|
FrameSkippingMode::Adaptive, // Adaptive by default
|
||||||
FrameSkipping::Disabled,
|
FrameSkippingMode::Adaptive,
|
||||||
FrameSkipping::Enabled,
|
FrameSkippingMode::Fixed,
|
||||||
"frame_skipping",
|
"frame_skipping_mode",
|
||||||
Category::Renderer,
|
Category::Renderer,
|
||||||
Specialization::Default,
|
Specialization::Default,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
SwitchableSetting<FrameSkippingMode, true> frame_skipping_mode{linkage,
|
|
||||||
FrameSkippingMode::Adaptive, // Adaptive by default
|
|
||||||
FrameSkippingMode::Adaptive,
|
|
||||||
FrameSkippingMode::Fixed,
|
|
||||||
"frame_skipping_mode",
|
|
||||||
Category::Renderer,
|
|
||||||
Specialization::Default,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
SwitchableSetting<u8, false> bg_red{
|
SwitchableSetting<u8, false> bg_red{
|
||||||
linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true};
|
linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true};
|
||||||
@@ -520,55 +496,54 @@ struct Values {
|
|||||||
|
|
||||||
// GC aggressiveness level for texture/buffer cache eviction
|
// GC aggressiveness level for texture/buffer cache eviction
|
||||||
SwitchableSetting<GCAggressiveness, true> gc_aggressiveness{linkage,
|
SwitchableSetting<GCAggressiveness, true> gc_aggressiveness{linkage,
|
||||||
GCAggressiveness::Light,
|
GCAggressiveness::Light,
|
||||||
GCAggressiveness::Off,
|
GCAggressiveness::Off,
|
||||||
GCAggressiveness::Light,
|
GCAggressiveness::Light,
|
||||||
"gc_aggressiveness",
|
"gc_aggressiveness",
|
||||||
Category::RendererAdvanced,
|
Category::RendererAdvanced,
|
||||||
Specialization::Default,
|
Specialization::Default,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
// Number of frames before unused textures are evicted (default 2)
|
// Number of frames before unused textures are evicted (default 2)
|
||||||
SwitchableSetting<u32, true> texture_eviction_frames{linkage,
|
SwitchableSetting<u32, true> texture_eviction_frames{linkage,
|
||||||
2, // default: 2 frames
|
2, // default: 2 frames
|
||||||
1, // min: 1 frame
|
1, // min: 1 frame
|
||||||
60, // max: 60 frames (1 second at 60fps)
|
60, // max: 60 frames (1 second at 60fps)
|
||||||
"texture_eviction_frames",
|
"texture_eviction_frames",
|
||||||
Category::RendererAdvanced,
|
|
||||||
Specialization::Default,
|
|
||||||
true,
|
|
||||||
true};
|
|
||||||
|
|
||||||
// Number of frames before unused buffers are evicted (default 5)
|
|
||||||
SwitchableSetting<u32, true> buffer_eviction_frames{linkage,
|
|
||||||
5, // default: 5 frames
|
|
||||||
1, // min: 1 frame
|
|
||||||
120, // max: 120 frames (2 seconds at 60fps)
|
|
||||||
"buffer_eviction_frames",
|
|
||||||
Category::RendererAdvanced,
|
Category::RendererAdvanced,
|
||||||
Specialization::Default,
|
Specialization::Default,
|
||||||
true,
|
true,
|
||||||
true};
|
true};
|
||||||
|
|
||||||
|
// Number of frames before unused buffers are evicted (default 5)
|
||||||
|
SwitchableSetting<u32, true> buffer_eviction_frames{linkage,
|
||||||
|
5, // default: 5 frames
|
||||||
|
1, // min: 1 frame
|
||||||
|
120, // max: 120 frames (2 seconds at 60fps)
|
||||||
|
"buffer_eviction_frames",
|
||||||
|
Category::RendererAdvanced,
|
||||||
|
Specialization::Default,
|
||||||
|
true,
|
||||||
|
true};
|
||||||
|
|
||||||
// Enable sparse texture priority eviction (evict large unmapped pages first)
|
// Enable sparse texture priority eviction (evict large unmapped pages first)
|
||||||
SwitchableSetting<bool> sparse_texture_priority_eviction{linkage, false,
|
SwitchableSetting<bool> sparse_texture_priority_eviction{
|
||||||
"sparse_texture_priority_eviction",
|
linkage, false, "sparse_texture_priority_eviction", Category::RendererAdvanced};
|
||||||
Category::RendererAdvanced};
|
|
||||||
|
|
||||||
// Enable VRAM usage logging for debugging
|
// Enable VRAM usage logging for debugging
|
||||||
SwitchableSetting<bool> log_vram_usage{linkage, false, "log_vram_usage",
|
SwitchableSetting<bool> log_vram_usage{linkage, false, "log_vram_usage",
|
||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
|
|
||||||
// FIXED: Android Adreno 740 native ASTC eviction
|
// FIXED: Android Adreno 740 native ASTC eviction
|
||||||
// Controls texture cache eviction strategy on Android devices with native ASTC support
|
// Controls texture cache eviction strategy on Android devices with native ASTC support
|
||||||
// Auto = detect based on GPU, Native = use compressed size, Decompress = use decompressed size
|
// Auto = detect based on GPU, Native = use compressed size, Decompress = use decompressed size
|
||||||
SwitchableSetting<AndroidAstcMode, true> android_astc_mode{linkage,
|
SwitchableSetting<AndroidAstcMode, true> android_astc_mode{linkage,
|
||||||
AndroidAstcMode::Auto,
|
AndroidAstcMode::Auto,
|
||||||
AndroidAstcMode::Auto,
|
AndroidAstcMode::Auto,
|
||||||
AndroidAstcMode::Decompress,
|
AndroidAstcMode::Decompress,
|
||||||
"android_astc_mode",
|
"android_astc_mode",
|
||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
|
|
||||||
SwitchableSetting<bool> async_presentation{linkage,
|
SwitchableSetting<bool> async_presentation{linkage,
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
@@ -605,12 +580,13 @@ struct Values {
|
|||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
|
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
|
||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
SwitchableSetting<ExtendedDynamicState, true> extended_dynamic_state{linkage,
|
SwitchableSetting<ExtendedDynamicState, true> extended_dynamic_state{
|
||||||
ExtendedDynamicState::EDS3,
|
linkage,
|
||||||
ExtendedDynamicState::Disabled,
|
ExtendedDynamicState::EDS3,
|
||||||
ExtendedDynamicState::EDS3,
|
ExtendedDynamicState::Disabled,
|
||||||
"extended_dynamic_state",
|
ExtendedDynamicState::EDS3,
|
||||||
Category::RendererAdvanced};
|
"extended_dynamic_state",
|
||||||
|
Category::RendererAdvanced};
|
||||||
SwitchableSetting<bool> use_conditional_rendering{linkage, true, "use_conditional_rendering",
|
SwitchableSetting<bool> use_conditional_rendering{linkage, true, "use_conditional_rendering",
|
||||||
Category::RendererAdvanced};
|
Category::RendererAdvanced};
|
||||||
|
|
||||||
@@ -676,7 +652,9 @@ struct Values {
|
|||||||
true};
|
true};
|
||||||
|
|
||||||
// Linux
|
// Linux
|
||||||
Setting<bool, false> is_wayland_platform{linkage, false, "is_wayland_platform", Category::Miscellaneous, Specialization::Default, false};
|
Setting<bool, false> is_wayland_platform{
|
||||||
|
linkage, false, "is_wayland_platform", Category::Miscellaneous, Specialization::Default,
|
||||||
|
false};
|
||||||
SwitchableSetting<bool> enable_gamemode{linkage, true, "enable_gamemode", Category::Linux};
|
SwitchableSetting<bool> enable_gamemode{linkage, true, "enable_gamemode", Category::Linux};
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
@@ -805,11 +783,12 @@ struct Values {
|
|||||||
Setting<std::string> web_api_url{linkage, "api.ynet-fun.xyz", "web_api_url",
|
Setting<std::string> web_api_url{linkage, "api.ynet-fun.xyz", "web_api_url",
|
||||||
Category::WebService};
|
Category::WebService};
|
||||||
Setting<std::string> citron_username{linkage, std::string(), "citron_username",
|
Setting<std::string> citron_username{linkage, std::string(), "citron_username",
|
||||||
Category::WebService};
|
Category::WebService};
|
||||||
Setting<std::string> citron_token{linkage, std::string(), "citron_token", Category::WebService};
|
Setting<std::string> citron_token{linkage, std::string(), "citron_token", Category::WebService};
|
||||||
|
|
||||||
// Updater
|
// Updater
|
||||||
Setting<bool> enable_auto_update_check{linkage, true, "enable_auto_update_check", Category::WebService};
|
Setting<bool> enable_auto_update_check{linkage, true, "enable_auto_update_check",
|
||||||
|
Category::WebService};
|
||||||
|
|
||||||
// Add-Ons
|
// Add-Ons
|
||||||
std::map<u64, std::vector<std::string>> disabled_addons;
|
std::map<u64, std::vector<std::string>> disabled_addons;
|
||||||
@@ -823,9 +802,12 @@ struct Values {
|
|||||||
// This stores the external path used for Intelligent Mirroring sync
|
// This stores the external path used for Intelligent Mirroring sync
|
||||||
std::map<u64, std::string> mirrored_save_paths;
|
std::map<u64, std::string> mirrored_save_paths;
|
||||||
|
|
||||||
Setting<bool> global_custom_save_path_enabled{linkage, false, "global_custom_save_path_enabled", Category::DataStorage};
|
Setting<bool> global_custom_save_path_enabled{linkage, false, "global_custom_save_path_enabled",
|
||||||
Setting<std::string> global_custom_save_path{linkage, std::string(), "global_custom_save_path", Category::DataStorage};
|
Category::DataStorage};
|
||||||
Setting<bool> backup_saves_to_nand{linkage, false, "backup_saves_to_nand", Category::DataStorage};
|
Setting<std::string> global_custom_save_path{linkage, std::string(), "global_custom_save_path",
|
||||||
|
Category::DataStorage};
|
||||||
|
Setting<bool> backup_saves_to_nand{linkage, false, "backup_saves_to_nand",
|
||||||
|
Category::DataStorage};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ template <>
|
|||||||
inline std::vector<std::pair<std::string, AudioEngine>>
|
inline std::vector<std::pair<std::string, AudioEngine>>
|
||||||
EnumMetadata<AudioEngine>::Canonicalizations() {
|
EnumMetadata<AudioEngine>::Canonicalizations() {
|
||||||
return {
|
return {
|
||||||
{"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2},
|
{"auto", AudioEngine::Auto}, {"cubeb", AudioEngine::Cubeb}, {"sdl2", AudioEngine::Sdl2},
|
||||||
{"openal", AudioEngine::OpenAL}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe},
|
{"openal", AudioEngine::OpenAL}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +110,7 @@ enum class AudioMode : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::vector<std::pair<std::string, AudioMode>>
|
inline std::vector<std::pair<std::string, AudioMode>> EnumMetadata<AudioMode>::Canonicalizations() {
|
||||||
EnumMetadata<AudioMode>::Canonicalizations() {
|
|
||||||
return {
|
return {
|
||||||
{"Mono", AudioMode::Mono},
|
{"Mono", AudioMode::Mono},
|
||||||
{"Stereo", AudioMode::Stereo},
|
{"Stereo", AudioMode::Stereo},
|
||||||
@@ -146,8 +145,7 @@ enum class Language : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::vector<std::pair<std::string, Language>>
|
inline std::vector<std::pair<std::string, Language>> EnumMetadata<Language>::Canonicalizations() {
|
||||||
EnumMetadata<Language>::Canonicalizations() {
|
|
||||||
return {
|
return {
|
||||||
{"Japanese", Language::Japanese},
|
{"Japanese", Language::Japanese},
|
||||||
{"EnglishAmerican", Language::EnglishAmerican},
|
{"EnglishAmerican", Language::EnglishAmerican},
|
||||||
@@ -186,15 +184,10 @@ enum class Region : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::vector<std::pair<std::string, Region>>
|
inline std::vector<std::pair<std::string, Region>> EnumMetadata<Region>::Canonicalizations() {
|
||||||
EnumMetadata<Region>::Canonicalizations() {
|
|
||||||
return {
|
return {
|
||||||
{"Japan", Region::Japan},
|
{"Japan", Region::Japan}, {"Usa", Region::Usa}, {"Europe", Region::Europe},
|
||||||
{"Usa", Region::Usa},
|
{"Australia", Region::Australia}, {"China", Region::China}, {"Korea", Region::Korea},
|
||||||
{"Europe", Region::Europe},
|
|
||||||
{"Australia", Region::Australia},
|
|
||||||
{"China", Region::China},
|
|
||||||
{"Korea", Region::Korea},
|
|
||||||
{"Taiwan", Region::Taiwan},
|
{"Taiwan", Region::Taiwan},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -254,8 +247,7 @@ enum class TimeZone : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::vector<std::pair<std::string, TimeZone>>
|
inline std::vector<std::pair<std::string, TimeZone>> EnumMetadata<TimeZone>::Canonicalizations() {
|
||||||
EnumMetadata<TimeZone>::Canonicalizations() {
|
|
||||||
return {
|
return {
|
||||||
{"Auto", TimeZone::Auto},
|
{"Auto", TimeZone::Auto},
|
||||||
{"Default", TimeZone::Default},
|
{"Default", TimeZone::Default},
|
||||||
@@ -388,8 +380,7 @@ enum class VSyncMode : u32 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline std::vector<std::pair<std::string, VSyncMode>>
|
inline std::vector<std::pair<std::string, VSyncMode>> EnumMetadata<VSyncMode>::Canonicalizations() {
|
||||||
EnumMetadata<VSyncMode>::Canonicalizations() {
|
|
||||||
return {
|
return {
|
||||||
{"Immediate", VSyncMode::Immediate},
|
{"Immediate", VSyncMode::Immediate},
|
||||||
{"Mailbox", VSyncMode::Mailbox},
|
{"Mailbox", VSyncMode::Mailbox},
|
||||||
@@ -543,12 +534,9 @@ template <>
|
|||||||
inline std::vector<std::pair<std::string, MemoryLayout>>
|
inline std::vector<std::pair<std::string, MemoryLayout>>
|
||||||
EnumMetadata<MemoryLayout>::Canonicalizations() {
|
EnumMetadata<MemoryLayout>::Canonicalizations() {
|
||||||
return {
|
return {
|
||||||
{"Memory_4Gb", MemoryLayout::Memory_4Gb},
|
{"Memory_4Gb", MemoryLayout::Memory_4Gb}, {"Memory_6Gb", MemoryLayout::Memory_6Gb},
|
||||||
{"Memory_6Gb", MemoryLayout::Memory_6Gb},
|
{"Memory_8Gb", MemoryLayout::Memory_8Gb}, {"Memory_10Gb", MemoryLayout::Memory_10Gb},
|
||||||
{"Memory_8Gb", MemoryLayout::Memory_8Gb},
|
{"Memory_12Gb", MemoryLayout::Memory_12Gb}, {"Memory_14Gb", MemoryLayout::Memory_14Gb},
|
||||||
{"Memory_10Gb", MemoryLayout::Memory_10Gb},
|
|
||||||
{"Memory_12Gb", MemoryLayout::Memory_12Gb},
|
|
||||||
{"Memory_14Gb", MemoryLayout::Memory_14Gb},
|
|
||||||
{"Memory_16Gb", MemoryLayout::Memory_16Gb},
|
{"Memory_16Gb", MemoryLayout::Memory_16Gb},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -625,9 +613,9 @@ enum class ResolutionSetup : s32 {
|
|||||||
Res1_2X = 0,
|
Res1_2X = 0,
|
||||||
Res3_4X = 1,
|
Res3_4X = 1,
|
||||||
Res1X = 2,
|
Res1X = 2,
|
||||||
Res5_4X = 11, // 1.25X
|
Res5_4X = 11, // 1.25X
|
||||||
Res3_2X = 3,
|
Res3_2X = 3,
|
||||||
Res7_4X = 12, // 1.75X
|
Res7_4X = 12, // 1.75X
|
||||||
Res2X = 4,
|
Res2X = 4,
|
||||||
Res3X = 5,
|
Res3X = 5,
|
||||||
Res4X = 6,
|
Res4X = 6,
|
||||||
@@ -641,20 +629,13 @@ template <>
|
|||||||
inline std::vector<std::pair<std::string, ResolutionSetup>>
|
inline std::vector<std::pair<std::string, ResolutionSetup>>
|
||||||
EnumMetadata<ResolutionSetup>::Canonicalizations() {
|
EnumMetadata<ResolutionSetup>::Canonicalizations() {
|
||||||
return {
|
return {
|
||||||
{"Res1_4X", ResolutionSetup::Res1_4X},
|
{"Res1_4X", ResolutionSetup::Res1_4X}, {"Res1_2X", ResolutionSetup::Res1_2X},
|
||||||
{"Res1_2X", ResolutionSetup::Res1_2X},
|
{"Res3_4X", ResolutionSetup::Res3_4X}, {"Res1X", ResolutionSetup::Res1X},
|
||||||
{"Res3_4X", ResolutionSetup::Res3_4X},
|
{"Res5_4X", ResolutionSetup::Res5_4X}, {"Res3_2X", ResolutionSetup::Res3_2X},
|
||||||
{"Res1X", ResolutionSetup::Res1X},
|
{"Res7_4X", ResolutionSetup::Res7_4X}, {"Res2X", ResolutionSetup::Res2X},
|
||||||
{"Res5_4X", ResolutionSetup::Res5_4X},
|
{"Res3X", ResolutionSetup::Res3X}, {"Res4X", ResolutionSetup::Res4X},
|
||||||
{"Res3_2X", ResolutionSetup::Res3_2X},
|
{"Res5X", ResolutionSetup::Res5X}, {"Res6X", ResolutionSetup::Res6X},
|
||||||
{"Res7_4X", ResolutionSetup::Res7_4X},
|
{"Res7X", ResolutionSetup::Res7X}, {"Res8X", ResolutionSetup::Res8X},
|
||||||
{"Res2X", ResolutionSetup::Res2X},
|
|
||||||
{"Res3X", ResolutionSetup::Res3X},
|
|
||||||
{"Res4X", ResolutionSetup::Res4X},
|
|
||||||
{"Res5X", ResolutionSetup::Res5X},
|
|
||||||
{"Res6X", ResolutionSetup::Res6X},
|
|
||||||
{"Res7X", ResolutionSetup::Res7X},
|
|
||||||
{"Res8X", ResolutionSetup::Res8X},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +656,8 @@ enum class ScalingFilter : u32 {
|
|||||||
Fsr2 = 8,
|
Fsr2 = 8,
|
||||||
CRTEasyMode = 9,
|
CRTEasyMode = 9,
|
||||||
CRTRoyale = 10,
|
CRTRoyale = 10,
|
||||||
MaxEnum = 11,
|
Cas = 11,
|
||||||
|
MaxEnum = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -693,6 +675,7 @@ EnumMetadata<ScalingFilter>::Canonicalizations() {
|
|||||||
{"Fsr2", ScalingFilter::Fsr2},
|
{"Fsr2", ScalingFilter::Fsr2},
|
||||||
{"CRTEasyMode", ScalingFilter::CRTEasyMode},
|
{"CRTEasyMode", ScalingFilter::CRTEasyMode},
|
||||||
{"CRTRoyale", ScalingFilter::CRTRoyale},
|
{"CRTRoyale", ScalingFilter::CRTRoyale},
|
||||||
|
{"Cas", ScalingFilter::Cas},
|
||||||
{"MaxEnum", ScalingFilter::MaxEnum},
|
{"MaxEnum", ScalingFilter::MaxEnum},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -714,10 +697,8 @@ template <>
|
|||||||
inline std::vector<std::pair<std::string, AntiAliasing>>
|
inline std::vector<std::pair<std::string, AntiAliasing>>
|
||||||
EnumMetadata<AntiAliasing>::Canonicalizations() {
|
EnumMetadata<AntiAliasing>::Canonicalizations() {
|
||||||
return {
|
return {
|
||||||
{"None", AntiAliasing::None},
|
{"None", AntiAliasing::None}, {"Fxaa", AntiAliasing::Fxaa},
|
||||||
{"Fxaa", AntiAliasing::Fxaa},
|
{"Smaa", AntiAliasing::Smaa}, {"Taa", AntiAliasing::Taa},
|
||||||
{"Smaa", AntiAliasing::Smaa},
|
|
||||||
{"Taa", AntiAliasing::Taa},
|
|
||||||
{"MaxEnum", AntiAliasing::MaxEnum},
|
{"MaxEnum", AntiAliasing::MaxEnum},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -805,12 +786,9 @@ template <>
|
|||||||
inline std::vector<std::pair<std::string, AspectRatio>>
|
inline std::vector<std::pair<std::string, AspectRatio>>
|
||||||
EnumMetadata<AspectRatio>::Canonicalizations() {
|
EnumMetadata<AspectRatio>::Canonicalizations() {
|
||||||
return {
|
return {
|
||||||
{"R16_9", AspectRatio::R16_9},
|
{"R16_9", AspectRatio::R16_9}, {"R4_3", AspectRatio::R4_3},
|
||||||
{"R4_3", AspectRatio::R4_3},
|
{"R21_9", AspectRatio::R21_9}, {"R16_10", AspectRatio::R16_10},
|
||||||
{"R21_9", AspectRatio::R21_9},
|
{"R32_9", AspectRatio::R32_9}, {"Stretch", AspectRatio::Stretch},
|
||||||
{"R16_10", AspectRatio::R16_10},
|
|
||||||
{"R32_9", AspectRatio::R32_9},
|
|
||||||
{"Stretch", AspectRatio::Stretch},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,8 +860,8 @@ inline u32 EnumMetadata<ExtendedDynamicState>::Index() {
|
|||||||
|
|
||||||
// FIXED: VRAM leak prevention - GC aggressiveness levels
|
// FIXED: VRAM leak prevention - GC aggressiveness levels
|
||||||
enum class GCAggressiveness : u32 {
|
enum class GCAggressiveness : u32 {
|
||||||
Off = 0, // Disable automatic GC (not recommended)
|
Off = 0, // Disable automatic GC (not recommended)
|
||||||
Light = 1, // Light GC - gentle eviction of old textures/buffers
|
Light = 1, // Light GC - gentle eviction of old textures/buffers
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ void BlitScreen::CreateWindowAdapt() {
|
|||||||
break;
|
break;
|
||||||
case Settings::ScalingFilter::Fsr:
|
case Settings::ScalingFilter::Fsr:
|
||||||
case Settings::ScalingFilter::Fsr2:
|
case Settings::ScalingFilter::Fsr2:
|
||||||
|
case Settings::ScalingFilter::Cas:
|
||||||
case Settings::ScalingFilter::Bilinear:
|
case Settings::ScalingFilter::Bilinear:
|
||||||
default:
|
default:
|
||||||
window_adapt = MakeBilinear(device);
|
window_adapt = MakeBilinear(device);
|
||||||
|
|||||||
@@ -49,11 +49,12 @@ FSR::FSR(u32 output_width_, u32 output_height_) : width(output_width_), height(o
|
|||||||
FSR::~FSR() = default;
|
FSR::~FSR() = default;
|
||||||
|
|
||||||
GLuint FSR::Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width,
|
GLuint FSR::Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width,
|
||||||
u32 input_image_height, const Common::Rectangle<f32>& crop_rect) {
|
u32 input_image_height, const Common::Rectangle<float>& crop_rect,
|
||||||
const f32 input_width = static_cast<f32>(input_image_width);
|
float sharpening) {
|
||||||
const f32 input_height = static_cast<f32>(input_image_height);
|
const float input_width = static_cast<float>(input_image_width);
|
||||||
const f32 output_width = static_cast<f32>(width);
|
const float input_height = static_cast<float>(input_image_height);
|
||||||
const f32 output_height = static_cast<f32>(height);
|
const float output_width = static_cast<float>(width);
|
||||||
|
const float output_height = static_cast<float>(height);
|
||||||
const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width;
|
const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width;
|
||||||
const f32 viewport_x = crop_rect.left * input_width;
|
const f32 viewport_x = crop_rect.left * input_width;
|
||||||
const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height;
|
const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height;
|
||||||
@@ -66,9 +67,6 @@ GLuint FSR::Draw(ProgramManager& program_manager, GLuint texture, u32 input_imag
|
|||||||
easu_con.data() + 12, viewport_width, viewport_height, input_width,
|
easu_con.data() + 12, viewport_width, viewport_height, input_width,
|
||||||
input_height, output_width, output_height, viewport_x, viewport_y);
|
input_height, output_width, output_height, viewport_x, viewport_y);
|
||||||
|
|
||||||
const float sharpening =
|
|
||||||
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
|
|
||||||
|
|
||||||
FsrRcasCon(rcas_con.data(), sharpening);
|
FsrRcasCon(rcas_con.data(), sharpening);
|
||||||
|
|
||||||
glProgramUniform4uiv(easu_frag.handle, 0, sizeof(easu_con), easu_con.data());
|
glProgramUniform4uiv(easu_frag.handle, 0, sizeof(easu_con), easu_con.data());
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public:
|
|||||||
~FSR();
|
~FSR();
|
||||||
|
|
||||||
GLuint Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width,
|
GLuint Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width,
|
||||||
u32 input_image_height, const Common::Rectangle<f32>& crop_rect);
|
u32 input_image_height, const Common::Rectangle<float>& crop_rect,
|
||||||
|
float sharpening);
|
||||||
|
|
||||||
bool NeedsRecreation(const Common::Rectangle<u32>& screen);
|
bool NeedsRecreation(const Common::Rectangle<u32>& screen);
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
|
|||||||
break;
|
break;
|
||||||
case Settings::AntiAliasing::Taa:
|
case Settings::AntiAliasing::Taa:
|
||||||
CreateTAA();
|
CreateTAA();
|
||||||
texture = taa->Draw(program_manager, info.display_texture,
|
texture = taa->Draw(program_manager, info.display_texture, GL_NONE, GL_NONE, GL_NONE,
|
||||||
GL_NONE, GL_NONE, GL_NONE, 0); // TODO: Add proper motion vectors
|
0); // TODO: Add proper motion vectors
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -75,12 +75,23 @@ GLuint Layer::ConfigureDraw(std::array<GLfloat, 3 * 2>& out_matrix,
|
|||||||
|
|
||||||
glDisablei(GL_SCISSOR_TEST, 0);
|
glDisablei(GL_SCISSOR_TEST, 0);
|
||||||
|
|
||||||
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr ||
|
||||||
|
filters.get_scaling_filter() == Settings::ScalingFilter::Cas) {
|
||||||
if (!fsr || fsr->NeedsRecreation(layout.screen)) {
|
if (!fsr || fsr->NeedsRecreation(layout.screen)) {
|
||||||
fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight());
|
fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop);
|
float sharpening = 0.0f;
|
||||||
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
|
||||||
|
sharpening =
|
||||||
|
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
|
||||||
|
} else if (filters.get_scaling_filter() == Settings::ScalingFilter::Cas) {
|
||||||
|
sharpening =
|
||||||
|
static_cast<float>(Settings::values.cas_sharpening_slider.GetValue()) / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop,
|
||||||
|
sharpening);
|
||||||
crop = {0, 0, 1, 1};
|
crop = {0, 0, 1, 1};
|
||||||
}
|
}
|
||||||
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr2) {
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr2) {
|
||||||
|
|||||||
@@ -5,14 +5,16 @@
|
|||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
#include "video_core/host_shaders/present_bicubic_frag_spv.h"
|
#include "video_core/host_shaders/present_bicubic_frag_spv.h"
|
||||||
#include "video_core/host_shaders/present_lanczos_frag_spv.h"
|
|
||||||
#include "video_core/host_shaders/present_gaussian_frag_spv.h"
|
#include "video_core/host_shaders/present_gaussian_frag_spv.h"
|
||||||
|
#include "video_core/host_shaders/present_lanczos_frag_spv.h"
|
||||||
|
#include "video_core/host_shaders/vulkan_crt_easymode_frag_spv.h"
|
||||||
|
#include "video_core/host_shaders/vulkan_fidelityfx_fsr_rcas_fp16_frag_spv.h"
|
||||||
|
#include "video_core/host_shaders/vulkan_fidelityfx_fsr_rcas_fp32_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scaleforce_fp16_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scaleforce_fp16_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scaleforce_fp32_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scaleforce_fp32_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scalefx_fp16_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scalefx_fp16_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_scalefx_fp32_frag_spv.h"
|
#include "video_core/host_shaders/vulkan_present_scalefx_fp32_frag_spv.h"
|
||||||
#include "video_core/host_shaders/vulkan_crt_easymode_frag_spv.h"
|
|
||||||
#include "video_core/renderer_vulkan/present/filters.h"
|
#include "video_core/renderer_vulkan/present/filters.h"
|
||||||
#include "video_core/renderer_vulkan/present/util.h"
|
#include "video_core/renderer_vulkan/present/util.h"
|
||||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||||
@@ -72,7 +74,8 @@ std::unique_ptr<WindowAdaptPass> MakeScaleFx(const Device& device, VkFormat fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format) {
|
std::unique_ptr<WindowAdaptPass> MakeLanczos(const Device& device, VkFormat frame_format) {
|
||||||
return std::make_unique<WindowAdaptPass>(device, frame_format, CreateNearestNeighborSampler(device),
|
return std::make_unique<WindowAdaptPass>(device, frame_format,
|
||||||
|
CreateNearestNeighborSampler(device),
|
||||||
BuildShader(device, PRESENT_LANCZOS_FRAG_SPV));
|
BuildShader(device, PRESENT_LANCZOS_FRAG_SPV));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ using PushConstants = std::array<u32, 4 * 4>;
|
|||||||
|
|
||||||
FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count,
|
FSR::FSR(const Device& device, MemoryAllocator& memory_allocator, size_t image_count,
|
||||||
VkExtent2D extent)
|
VkExtent2D extent)
|
||||||
: m_device{device}, m_memory_allocator{memory_allocator},
|
: m_device{device}, m_memory_allocator{memory_allocator}, m_image_count{image_count},
|
||||||
m_image_count{image_count}, m_extent{extent} {
|
m_extent{extent} {
|
||||||
|
|
||||||
CreateImages();
|
CreateImages();
|
||||||
CreateRenderPasses();
|
CreateRenderPasses();
|
||||||
@@ -157,7 +157,7 @@ void FSR::UploadImages(Scheduler& scheduler) {
|
|||||||
|
|
||||||
VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,
|
VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,
|
||||||
VkImageView source_image_view, VkExtent2D input_image_extent,
|
VkImageView source_image_view, VkExtent2D input_image_extent,
|
||||||
const Common::Rectangle<f32>& crop_rect) {
|
const Common::Rectangle<f32>& crop_rect, float sharpening) {
|
||||||
Images& images = m_dynamic_images[image_index];
|
Images& images = m_dynamic_images[image_index];
|
||||||
|
|
||||||
VkImage easu_image = *images.images[Easu];
|
VkImage easu_image = *images.images[Easu];
|
||||||
@@ -188,8 +188,6 @@ VkImageView FSR::Draw(Scheduler& scheduler, size_t image_index, VkImage source_i
|
|||||||
input_image_height, output_image_width, output_image_height, viewport_x,
|
input_image_height, output_image_width, output_image_height, viewport_x,
|
||||||
viewport_y);
|
viewport_y);
|
||||||
|
|
||||||
const float sharpening =
|
|
||||||
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
|
|
||||||
FsrRcasCon(rcas_con.data(), sharpening);
|
FsrRcasCon(rcas_con.data(), sharpening);
|
||||||
|
|
||||||
UploadImages(scheduler);
|
UploadImages(scheduler);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
VkExtent2D extent);
|
VkExtent2D extent);
|
||||||
VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,
|
VkImageView Draw(Scheduler& scheduler, size_t image_index, VkImage source_image,
|
||||||
VkImageView source_image_view, VkExtent2D input_image_extent,
|
VkImageView source_image_view, VkExtent2D input_image_extent,
|
||||||
const Common::Rectangle<f32>& crop_rect);
|
const Common::Rectangle<f32>& crop_rect, float sharpening);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateImages();
|
void CreateImages();
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ Layer::Layer(const Device& device_, MemoryAllocator& memory_allocator_, Schedule
|
|||||||
device_memory(device_memory_), filters(filters_), image_count(image_count_) {
|
device_memory(device_memory_), filters(filters_), image_count(image_count_) {
|
||||||
CreateDescriptorPool();
|
CreateDescriptorPool();
|
||||||
CreateDescriptorSets(layout);
|
CreateDescriptorSets(layout);
|
||||||
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr ||
|
||||||
|
filters.get_scaling_filter() == Settings::ScalingFilter::Cas) {
|
||||||
CreateFSR(output_size);
|
CreateFSR(output_size);
|
||||||
}
|
}
|
||||||
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr2) {
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr2) {
|
||||||
@@ -109,8 +110,16 @@ void Layer::ConfigureDraw(PresentPushConstants* out_push_constants,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (fsr) {
|
if (fsr) {
|
||||||
|
float sharpening = 0.0f;
|
||||||
|
if (filters.get_scaling_filter() == Settings::ScalingFilter::Fsr) {
|
||||||
|
sharpening =
|
||||||
|
static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
|
||||||
|
} else if (filters.get_scaling_filter() == Settings::ScalingFilter::Cas) {
|
||||||
|
sharpening =
|
||||||
|
static_cast<float>(Settings::values.cas_sharpening_slider.GetValue()) / 100.0f;
|
||||||
|
}
|
||||||
source_image_view = fsr->Draw(scheduler, image_index, source_image, source_image_view,
|
source_image_view = fsr->Draw(scheduler, image_index, source_image, source_image_view,
|
||||||
render_extent, crop_rect);
|
render_extent, crop_rect, sharpening);
|
||||||
crop_rect = {0, 0, 1, 1};
|
crop_rect = {0, 0, 1, 1};
|
||||||
}
|
}
|
||||||
if (fsr2) {
|
if (fsr2) {
|
||||||
@@ -257,7 +266,8 @@ void Layer::UpdateDescriptorSet(VkImageView image_view, VkSampler sampler, size_
|
|||||||
const VkDescriptorImageInfo image_info{
|
const VkDescriptorImageInfo image_info{
|
||||||
.sampler = sampler,
|
.sampler = sampler,
|
||||||
.imageView = image_view,
|
.imageView = image_view,
|
||||||
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // Correct layout for texture sampling
|
.imageLayout =
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // Correct layout for texture sampling
|
||||||
};
|
};
|
||||||
|
|
||||||
const VkWriteDescriptorSet sampler_write{
|
const VkWriteDescriptorSet sampler_write{
|
||||||
@@ -294,7 +304,7 @@ void Layer::UpdateRawImage(const Tegra::FramebufferConfig& framebuffer, size_t i
|
|||||||
Tegra::Texture::UnswizzleTexture(
|
Tegra::Texture::UnswizzleTexture(
|
||||||
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
|
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
|
||||||
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
|
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
|
||||||
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
|
buffer.Flush(); // Ensure host writes are visible before the GPU copy.
|
||||||
}
|
}
|
||||||
|
|
||||||
const VkBufferImageCopy copy{
|
const VkBufferImageCopy copy{
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/frontend/framebuffer_layout.h"
|
#include "core/frontend/framebuffer_layout.h"
|
||||||
#include "video_core/framebuffer_config.h"
|
#include "video_core/framebuffer_config.h"
|
||||||
|
#include "video_core/fsr.h"
|
||||||
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
|
#include "video_core/host_shaders/vulkan_present_vert_spv.h"
|
||||||
#include "video_core/renderer_vulkan/present/layer.h"
|
#include "video_core/renderer_vulkan/present/layer.h"
|
||||||
#include "video_core/renderer_vulkan/present/present_push_constants.h"
|
#include "video_core/renderer_vulkan/present/present_push_constants.h"
|
||||||
@@ -13,7 +15,6 @@
|
|||||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||||
#include "video_core/vulkan_common/vulkan_device.h"
|
#include "video_core/vulkan_common/vulkan_device.h"
|
||||||
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
||||||
#include "common/settings.h"
|
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
@@ -93,8 +94,9 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
|||||||
cmdbuf.ClearAttachments({clear_attachment}, {clear_rect});
|
cmdbuf.ClearAttachments({clear_attachment}, {clear_rect});
|
||||||
|
|
||||||
const auto current_scaling_filter = Settings::values.scaling_filter.GetValue();
|
const auto current_scaling_filter = Settings::values.scaling_filter.GetValue();
|
||||||
const bool is_crt_enabled = current_scaling_filter == Settings::ScalingFilter::CRTEasyMode ||
|
const bool is_crt_enabled =
|
||||||
current_scaling_filter == Settings::ScalingFilter::CRTRoyale;
|
current_scaling_filter == Settings::ScalingFilter::CRTEasyMode ||
|
||||||
|
current_scaling_filter == Settings::ScalingFilter::CRTRoyale;
|
||||||
|
|
||||||
for (size_t i = 0; i < layer_count; i++) {
|
for (size_t i = 0; i < layer_count; i++) {
|
||||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipelines[i]);
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipelines[i]);
|
||||||
@@ -139,6 +141,7 @@ void WindowAdaptPass::Draw(RasterizerVulkan& rasterizer, Scheduler& scheduler, s
|
|||||||
|
|
||||||
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_layout, 0,
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, graphics_pipeline_layout, 0,
|
||||||
descriptor_sets[i], {});
|
descriptor_sets[i], {});
|
||||||
|
|
||||||
cmdbuf.Draw(4, 1, 0, 0);
|
cmdbuf.Draw(4, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ void BlitScreen::SetWindowAdaptPass() {
|
|||||||
case Settings::ScalingFilter::CRTRoyale:
|
case Settings::ScalingFilter::CRTRoyale:
|
||||||
window_adapt = MakeCRT(device, swapchain_view_format);
|
window_adapt = MakeCRT(device, swapchain_view_format);
|
||||||
break;
|
break;
|
||||||
|
case Settings::ScalingFilter::Cas:
|
||||||
case Settings::ScalingFilter::Fsr:
|
case Settings::ScalingFilter::Fsr:
|
||||||
case Settings::ScalingFilter::Fsr2:
|
case Settings::ScalingFilter::Fsr2:
|
||||||
case Settings::ScalingFilter::Bilinear:
|
case Settings::ScalingFilter::Bilinear:
|
||||||
|
|||||||
Reference in New Issue
Block a user