fix/feat: Introduce CAS & Add Dynamic Slider Viewing for Toggled WAF's, and remove Android ASTC visibility on PC

This commit is contained in:
collecting
2026-02-05 02:57:28 -05:00
parent 9443737034
commit 37dd2fddc4
18 changed files with 388 additions and 324 deletions

View File

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

View File

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

View File

@@ -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() {

View File

@@ -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)")),

View File

@@ -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 = {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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{

View File

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

View File

@@ -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: