diff --git a/src/citron/configuration/configure_graphics.cpp b/src/citron/configuration/configure_graphics.cpp index 0c814b043..f3910ebaf 100644 --- a/src/citron/configuration/configure_graphics.cpp +++ b/src/citron/configuration/configure_graphics.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -288,6 +289,11 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) { continue; } + // Store reference to the FSR sharpness widget for later use + if (setting->Id() == Settings::values.fsr_sharpening_slider.Id()) { + fsr_sharpness_widget = widget; + } + if (setting->Id() == Settings::values.renderer_backend.Id()) { // Add the renderer combobox now so it's at the top api_grid_layout->addWidget(widget); @@ -366,6 +372,41 @@ void ConfigureGraphics::Setup(const ConfigurationShared::Builder& builder) { api_grid_layout->addWidget(widget); } + // Set up FSR sharpness slider conditional enabling + if (fsr_sharpness_widget) { + // Create a function to update the enabled state based on scaling filter + auto update_fsr_sharpness_enabled = [this]() { + if (fsr_sharpness_widget) { + const auto scaling_filter = Settings::values.scaling_filter.GetValue(); + const bool fsr2_selected = (scaling_filter == Settings::ScalingFilter::Fsr2); + fsr_sharpness_widget->setEnabled(!fsr2_selected); + + // Grey out the widget when disabled + if (fsr2_selected) { + fsr_sharpness_widget->setStyleSheet(QStringLiteral("QWidget { color: gray; }")); + } else { + fsr_sharpness_widget->setStyleSheet(QStringLiteral("")); + } + } + }; + + // Initial state + update_fsr_sharpness_enabled(); + + // Connect to scaling filter changes + if (!Settings::IsConfiguringGlobal()) { + // Find the scaling filter widget and connect to its changes + for (const auto& [id, widget] : hold_graphics) { + if (id == Settings::values.scaling_filter.Id()) { + auto* config_widget = static_cast(widget); + QObject::connect(config_widget->combobox, QOverload::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 // (3 settings, all collected into a single widget with a QColor to manage on top) if (Settings::IsConfiguringGlobal()) { diff --git a/src/citron/configuration/configure_graphics.h b/src/citron/configuration/configure_graphics.h index eae4a627a..33ae92031 100644 --- a/src/citron/configuration/configure_graphics.h +++ b/src/citron/configuration/configure_graphics.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -113,4 +114,5 @@ private: QWidget* shader_backend_widget; QComboBox* aspect_ratio_combobox; QComboBox* resolution_combobox; + QWidget* fsr_sharpness_widget; }; diff --git a/src/citron/configuration/shared_translation.cpp b/src/citron/configuration/shared_translation.cpp index b95c09158..aa9e2482d 100644 --- a/src/citron/configuration/shared_translation.cpp +++ b/src/citron/configuration/shared_translation.cpp @@ -404,6 +404,13 @@ std::unique_ptr ComboboxEnumeration(QWidget* parent) { PAIR(AntiAliasing, Fxaa, tr("FXAA")), PAIR(AntiAliasing, Smaa, tr("SMAA")), }}); + translations->insert({Settings::EnumMetadata::Index(), + { + PAIR(FSR2QualityMode, Quality, tr("Quality")), + PAIR(FSR2QualityMode, Balanced, tr("Balanced")), + PAIR(FSR2QualityMode, Performance, tr("Performance")), + PAIR(FSR2QualityMode, UltraPerformance, tr("Ultra Performance")), + }}); translations->insert({Settings::EnumMetadata::Index(), { PAIR(AspectRatio, R16_9, tr("Default (16:9)")), diff --git a/src/common/settings.h b/src/common/settings.h index b1c7b5233..dd82c4994 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -348,15 +348,15 @@ struct Values { true, true}; - SwitchableSetting fsr2_quality_mode{linkage, - 2, // Performance by default - 0, // Quality - 3, // Ultra Performance - "fsr2_quality_mode", - Category::Renderer, - Specialization::Default, - true, - true}; + SwitchableSetting fsr2_quality_mode{linkage, + FSR2QualityMode::Performance, // Performance by default + FSR2QualityMode::Quality, + FSR2QualityMode::UltraPerformance, + "fsr2_quality_mode", + Category::Renderer, + Specialization::Default, + true, + true}; SwitchableSetting bg_red{ linkage, 0, "bg_red", Category::Renderer, Specialization::Default, true, true}; diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index ee701cb5d..6151e7619 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -151,6 +151,8 @@ ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Gaussian, ScaleForce, Fs ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); +ENUM(FSR2QualityMode, Quality, Balanced, Performance, UltraPerformance); + ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, R32_9, Stretch); ENUM(ConsoleMode, Handheld, Docked); diff --git a/src/video_core/renderer_opengl/present/fsr2.cpp b/src/video_core/renderer_opengl/present/fsr2.cpp index fcf9ecf10..572ab6595 100644 --- a/src/video_core/renderer_opengl/present/fsr2.cpp +++ b/src/video_core/renderer_opengl/present/fsr2.cpp @@ -67,22 +67,22 @@ GLuint FSR2::Draw(ProgramManager& program_manager, GLuint texture, u32 input_ima easu_con.data() + 12, viewport_width, viewport_height, input_width, input_height, output_width, output_height, viewport_x, viewport_y); - // FSR 2.0 uses a different sharpening calculation based on quality mode - const int quality_mode = Settings::values.fsr2_quality_mode.GetValue(); - const float sharpening = [quality_mode]() { - switch (quality_mode) { - case 0: // Quality - return 0.2f; - case 1: // Balanced - return 0.4f; - case 2: // Performance - return 0.6f; - case 3: // Ultra Performance - return 0.8f; - default: - return 0.4f; - } - }(); + // FSR 2.0 uses a different sharpening calculation based on quality mode + const auto quality_mode = Settings::values.fsr2_quality_mode.GetValue(); + const float sharpening = [quality_mode]() { + switch (quality_mode) { + case Settings::FSR2QualityMode::Quality: + return 0.2f; + case Settings::FSR2QualityMode::Balanced: + return 0.4f; + case Settings::FSR2QualityMode::Performance: + return 0.6f; + case Settings::FSR2QualityMode::UltraPerformance: + return 0.8f; + default: + return 0.4f; + } + }(); FsrRcasCon(rcas_con.data(), sharpening); diff --git a/src/video_core/renderer_vulkan/present/fsr2.cpp b/src/video_core/renderer_vulkan/present/fsr2.cpp index d8bcb2211..714f12942 100644 --- a/src/video_core/renderer_vulkan/present/fsr2.cpp +++ b/src/video_core/renderer_vulkan/present/fsr2.cpp @@ -188,22 +188,22 @@ VkImageView FSR2::Draw(Scheduler& scheduler, size_t image_index, VkImage source_ input_image_height, output_image_width, output_image_height, viewport_x, viewport_y); - // FSR 2.0 uses a different sharpening calculation based on quality mode - const int quality_mode = Settings::values.fsr2_quality_mode.GetValue(); - const float sharpening = [quality_mode]() { - switch (quality_mode) { - case 0: // Quality - return 0.2f; - case 1: // Balanced - return 0.4f; - case 2: // Performance - return 0.6f; - case 3: // Ultra Performance - return 0.8f; - default: - return 0.4f; - } - }(); + // FSR 2.0 uses a different sharpening calculation based on quality mode + const auto quality_mode = Settings::values.fsr2_quality_mode.GetValue(); + const float sharpening = [quality_mode]() { + switch (quality_mode) { + case Settings::FSR2QualityMode::Quality: + return 0.2f; + case Settings::FSR2QualityMode::Balanced: + return 0.4f; + case Settings::FSR2QualityMode::Performance: + return 0.6f; + case Settings::FSR2QualityMode::UltraPerformance: + return 0.8f; + default: + return 0.4f; + } + }(); FsrRcasCon(rcas_con.data(), sharpening); UploadImages(scheduler);