summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/bit_util.h7
-rw-r--r--src/common/math_util.h4
-rw-r--r--src/common/settings.cpp54
-rw-r--r--src/common/settings.h61
4 files changed, 120 insertions, 6 deletions
diff --git a/src/common/bit_util.h b/src/common/bit_util.h
index 64520ca4e..eef8c1c5a 100644
--- a/src/common/bit_util.h
+++ b/src/common/bit_util.h
@@ -7,6 +7,7 @@
#include <bit>
#include <climits>
#include <cstddef>
+#include <type_traits>
#include "common/common_types.h"
@@ -44,4 +45,10 @@ template <typename T>
return static_cast<u32>(log2_f + static_cast<u64>((value ^ (1ULL << log2_f)) != 0ULL));
}
+template <typename T>
+requires std::is_integral_v<T>
+[[nodiscard]] T NextPow2(T value) {
+ return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U)));
+}
+
} // namespace Common
diff --git a/src/common/math_util.h b/src/common/math_util.h
index 4c38d8040..510c4e56d 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -48,8 +48,8 @@ struct Rectangle {
}
[[nodiscard]] Rectangle<T> Scale(const float s) const {
- return Rectangle{left, top, static_cast<T>(left + GetWidth() * s),
- static_cast<T>(top + GetHeight() * s)};
+ return Rectangle{left, top, static_cast<T>(static_cast<float>(left + GetWidth()) * s),
+ static_cast<T>(static_cast<float>(top + GetHeight()) * s)};
}
};
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 9dd5e3efb..6964a8273 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -47,7 +47,9 @@ void LogSettings() {
log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue());
- log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
+ log_setting("Renderer_UseResolutionScaling", values.resolution_setup.GetValue());
+ log_setting("Renderer_ScalingFilter", values.scaling_filter.GetValue());
+ log_setting("Renderer_AntiAliasing", values.anti_aliasing.GetValue());
log_setting("Renderer_UseSpeedLimit", values.use_speed_limit.GetValue());
log_setting("Renderer_SpeedLimit", values.speed_limit.GetValue());
log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
@@ -105,6 +107,55 @@ float Volume() {
return values.volume.GetValue() / 100.0f;
}
+void UpdateRescalingInfo() {
+ const auto setup = values.resolution_setup.GetValue();
+ auto& info = values.resolution_info;
+ info.downscale = false;
+ switch (setup) {
+ case ResolutionSetup::Res1_2X:
+ info.up_scale = 1;
+ info.down_shift = 1;
+ info.downscale = true;
+ break;
+ case ResolutionSetup::Res3_4X:
+ info.up_scale = 3;
+ info.down_shift = 2;
+ info.downscale = true;
+ break;
+ case ResolutionSetup::Res1X:
+ info.up_scale = 1;
+ info.down_shift = 0;
+ break;
+ case ResolutionSetup::Res2X:
+ info.up_scale = 2;
+ info.down_shift = 0;
+ break;
+ case ResolutionSetup::Res3X:
+ info.up_scale = 3;
+ info.down_shift = 0;
+ break;
+ case ResolutionSetup::Res4X:
+ info.up_scale = 4;
+ info.down_shift = 0;
+ break;
+ case ResolutionSetup::Res5X:
+ info.up_scale = 5;
+ info.down_shift = 0;
+ break;
+ case ResolutionSetup::Res6X:
+ info.up_scale = 6;
+ info.down_shift = 0;
+ break;
+ default:
+ UNREACHABLE();
+ info.up_scale = 1;
+ info.down_shift = 0;
+ }
+ info.up_factor = static_cast<f32>(info.up_scale) / (1U << info.down_shift);
+ info.down_factor = static_cast<f32>(1U << info.down_shift) / info.up_scale;
+ info.active = info.up_scale != 1 || info.down_shift != 0;
+}
+
void RestoreGlobalState(bool is_powered_on) {
// If a game is running, DO NOT restore the global settings state
if (is_powered_on) {
@@ -132,6 +183,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.max_anisotropy.SetGlobal(true);
values.use_speed_limit.SetGlobal(true);
values.speed_limit.SetGlobal(true);
+ values.fps_cap.SetGlobal(true);
values.use_disk_shader_cache.SetGlobal(true);
values.gpu_accuracy.SetGlobal(true);
values.use_asynchronous_gpu_emulation.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index 9ff4cf85d..fa4aa8747 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -52,6 +52,56 @@ enum class NvdecEmulation : u32 {
GPU = 2,
};
+enum class ResolutionSetup : u32 {
+ Res1_2X = 0,
+ Res3_4X = 1,
+ Res1X = 2,
+ Res2X = 3,
+ Res3X = 4,
+ Res4X = 5,
+ Res5X = 6,
+ Res6X = 7,
+};
+
+enum class ScalingFilter : u32 {
+ NearestNeighbor = 0,
+ Bilinear = 1,
+ Bicubic = 2,
+ Gaussian = 3,
+ ScaleForce = 4,
+ Fsr = 5,
+ LastFilter = Fsr,
+};
+
+enum class AntiAliasing : u32 {
+ None = 0,
+ Fxaa = 1,
+ LastAA = Fxaa,
+};
+
+struct ResolutionScalingInfo {
+ u32 up_scale{1};
+ u32 down_shift{0};
+ f32 up_factor{1.0f};
+ f32 down_factor{1.0f};
+ bool active{};
+ bool downscale{};
+
+ s32 ScaleUp(s32 value) const {
+ if (value == 0) {
+ return 0;
+ }
+ return std::max((value * static_cast<s32>(up_scale)) >> static_cast<s32>(down_shift), 1);
+ }
+
+ u32 ScaleUp(u32 value) const {
+ if (value == 0U) {
+ return 0U;
+ }
+ return std::max((value * up_scale) >> down_shift, 1U);
+ }
+};
+
/** The BasicSetting class is a simple resource manager. It defines a label and default value
* alongside the actual value of the setting for simpler and less-error prone use with frontend
* configurations. Setting a default value and label is required, though subclasses may deviate from
@@ -451,7 +501,10 @@ struct Values {
"disable_shader_loop_safety_checks"};
Setting<int> vulkan_device{0, "vulkan_device"};
- Setting<u16> resolution_factor{1, "resolution_factor"};
+ ResolutionScalingInfo resolution_info{};
+ Setting<ResolutionSetup> resolution_setup{ResolutionSetup::Res1X, "resolution_setup"};
+ Setting<ScalingFilter> scaling_filter{ScalingFilter::Bilinear, "scaling_filter"};
+ Setting<AntiAliasing> anti_aliasing{AntiAliasing::None, "anti_aliasing"};
// *nix platforms may have issues with the borderless windowed fullscreen mode.
// Default to exclusive fullscreen on these platforms for now.
RangedSetting<FullscreenMode> fullscreen_mode{
@@ -462,7 +515,7 @@ struct Values {
#endif
FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
RangedSetting<int> aspect_ratio{0, 0, 3, "aspect_ratio"};
- RangedSetting<int> max_anisotropy{0, 0, 4, "max_anisotropy"};
+ RangedSetting<int> max_anisotropy{0, 0, 5, "max_anisotropy"};
Setting<bool> use_speed_limit{true, "use_speed_limit"};
RangedSetting<u16> speed_limit{100, 0, 9999, "speed_limit"};
Setting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
@@ -472,7 +525,7 @@ struct Values {
Setting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
Setting<bool> accelerate_astc{true, "accelerate_astc"};
Setting<bool> use_vsync{true, "use_vsync"};
- BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
+ RangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
RangedSetting<ShaderBackend> shader_backend{ShaderBackend::GLASM, ShaderBackend::GLSL,
ShaderBackend::SPIRV, "shader_backend"};
@@ -595,6 +648,8 @@ std::string GetTimeZoneString();
void LogSettings();
+void UpdateRescalingInfo();
+
// Restore the global state of all applicable settings in the Values struct
void RestoreGlobalState(bool is_powered_on);