diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt index 2c8cbf2a1..02d6a79ae 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt @@ -18,7 +18,7 @@ enum class IntSetting( CAMERA_OUTER_LEFT_FLIP(SettingKeys.camera_outer_left_flip(), Settings.SECTION_CAMERA, 0), CAMERA_OUTER_RIGHT_FLIP(SettingKeys.camera_outer_right_flip(), Settings.SECTION_CAMERA, 0), GRAPHICS_API(SettingKeys.graphics_api(), Settings.SECTION_RENDERER, 1), - RESOLUTION_FACTOR(SettingKeys.resolution_factor(), Settings.SECTION_RENDERER, 1), + RESOLUTION_FACTOR(SettingKeys.resolution_factor(), Settings.SECTION_RENDERER, 100), STEREOSCOPIC_3D_MODE(SettingKeys.render_3d(), Settings.SECTION_RENDERER, 2), STEREOSCOPIC_3D_DEPTH(SettingKeys.factor_3d(), Settings.SECTION_RENDERER, 0), STEPS_PER_HOUR(SettingKeys.steps_per_hour(), Settings.SECTION_SYSTEM, 0), diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index e0fa260c5..83c024934 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -150,6 +150,12 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.use_hw_shader); ReadSetting("Renderer", Settings::values.use_shader_jit); ReadSetting("Renderer", Settings::values.resolution_factor); + { + const u32 rf = Settings::values.resolution_factor.GetValue(); + if (rf >= 1 && rf <= 10) { + Settings::values.resolution_factor.SetValue(rf * 100); + } + } ReadSetting("Renderer", Settings::values.use_disk_shader_cache); ReadSetting("Renderer", Settings::values.use_vsync); ReadSetting("Renderer", Settings::values.texture_filter); diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 2a08cd546..b694b307d 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -374,29 +374,49 @@ @string/internal_resolution_setting_auto + @string/internal_resolution_setting_0_5x @string/internal_resolution_setting_1x + @string/internal_resolution_setting_1_5x @string/internal_resolution_setting_2x + @string/internal_resolution_setting_2_5x @string/internal_resolution_setting_3x + @string/internal_resolution_setting_3_5x @string/internal_resolution_setting_4x + @string/internal_resolution_setting_4_5x @string/internal_resolution_setting_5x + @string/internal_resolution_setting_5_5x @string/internal_resolution_setting_6x + @string/internal_resolution_setting_6_5x @string/internal_resolution_setting_7x + @string/internal_resolution_setting_7_5x @string/internal_resolution_setting_8x + @string/internal_resolution_setting_8_5x @string/internal_resolution_setting_9x + @string/internal_resolution_setting_9_5x @string/internal_resolution_setting_10x 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 + 50 + 100 + 150 + 200 + 250 + 300 + 350 + 400 + 450 + 500 + 550 + 600 + 650 + 700 + 750 + 800 + 850 + 900 + 950 + 1000 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 750677fd5..b21c9583e 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -284,15 +284,25 @@ Internal Resolution Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain applications. Auto (Screen Size) + 0.5x Native (200x120) Native (400x240) + 1.5x Native (600x360) 2x Native (800x480) + 2.5x Native (1000x600) 3x Native (1200x720) + 3.5x Native (1400x840) 4x Native (1600x960) + 4.5x Native (1800x1080) 5x Native (2000x1200) + 5.5x Native (2200x1320) 6x Native (2400x1440) + 6.5x Native (2600x1560) 7x Native (2800x1680) + 7.5x Native (3000x1800) 8x Native (3200x1920) + 8.5x Native (3400x2040) 9x Native (3600x2160) + 9.5x Native (3800x2280) 10x Native (4000x2400) Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled. Warning: Modifying these settings will slow emulation diff --git a/src/citra_libretro/core_settings.cpp b/src/citra_libretro/core_settings.cpp index 085f7ac52..f68001f4d 100644 --- a/src/citra_libretro/core_settings.cpp +++ b/src/citra_libretro/core_settings.cpp @@ -363,19 +363,29 @@ static constexpr retro_core_option_v2_definition option_definitions[] = { nullptr, config::category::graphics, { - { "1", "1x (Native 400x240)" }, - { "2", "2x (800x480)" }, - { "3", "3x (1200x720)" }, - { "4", "4x (1600x960)" }, - { "5", "5x (2000x1200)" }, - { "6", "6x (2400x1440)" }, - { "7", "7x (2800x1680)" }, - { "8", "8x (3200x1920)" }, - { "9", "9x (3600x2160)" }, - { "10", "10x (4000x2400)" }, + { "50", "0.5x (200x120)" }, + { "100", "1x Native (400x240)" }, + { "150", "1.5x (600x360)" }, + { "200", "2x (800x480)" }, + { "250", "2.5x (1000x600)" }, + { "300", "3x (1200x720)" }, + { "350", "3.5x (1400x840)" }, + { "400", "4x (1600x960)" }, + { "450", "4.5x (1800x1080)" }, + { "500", "5x (2000x1200)" }, + { "550", "5.5x (2200x1320)" }, + { "600", "6x (2400x1440)" }, + { "650", "6.5x (2600x1560)" }, + { "700", "7x (2800x1680)" }, + { "750", "7.5x (3000x1800)" }, + { "800", "8x (3200x1920)" }, + { "850", "8.5x (3400x2040)" }, + { "900", "9x (3600x2160)" }, + { "950", "9.5x (3800x2280)" }, + { "1000", "10x (4000x2400)" }, { nullptr, nullptr } }, - "1" + "100" }, { config::graphics::texture_filter, @@ -922,7 +932,7 @@ static void ParseGraphicsOptions(void) { LibRetro::FetchVariable(config::graphics::use_disk_shader_cache, config::enabled) == config::enabled; - auto resolution = LibRetro::FetchVariable(config::graphics::resolution_factor, "1"); + auto resolution = LibRetro::FetchVariable(config::graphics::resolution_factor, "100"); Settings::values.resolution_factor = std::stoi(resolution); Settings::values.texture_filter = diff --git a/src/citra_libretro/emu_window/libretro_window.cpp b/src/citra_libretro/emu_window/libretro_window.cpp index 8e8532566..a4654fdfc 100644 --- a/src/citra_libretro/emu_window/libretro_window.cpp +++ b/src/citra_libretro/emu_window/libretro_window.cpp @@ -239,7 +239,7 @@ LayoutGeometry ComputeLayoutGeometry() { unsigned baseY; bool emulated_pointer = true; - float scaling = Settings::values.resolution_factor.GetValue(); + float scaling = Settings::values.resolution_factor.GetValue() / 100.0f; bool swapped = Settings::values.swap_screen.GetValue(); switch (Settings::values.layout_option.GetValue()) { @@ -264,7 +264,7 @@ LayoutGeometry ComputeLayoutGeometry() { baseY = Core::kScreenTopHeight; } - if (scaling < 4) { + if (scaling < 4.0f) { // Unfortunately, to get this aspect ratio correct (and have non-blurry 1x scaling), // we have to have a pretty large buffer for the minimum ratio. baseX *= 4; diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index a5aa9896b..80336812d 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -708,6 +708,14 @@ void QtConfig::ReadRendererValues() { ReadGlobalSetting(Settings::values.use_vsync); ReadGlobalSetting(Settings::values.use_display_refresh_rate_detection); ReadGlobalSetting(Settings::values.resolution_factor); + { + const u32 rf = Settings::values.resolution_factor.GetValue(); + if (rf >= 1 && rf <= 10) { + LOG_WARNING(Frontend, "Migrating old resolution factor value of {} to new value of {}", + rf, rf * 100); + Settings::values.resolution_factor.SetValue(rf * 100); + } + } ReadGlobalSetting(Settings::values.use_integer_scaling); ReadGlobalSetting(Settings::values.frame_limit); ReadGlobalSetting(Settings::values.turbo_limit); @@ -828,6 +836,16 @@ void QtConfig::ReadUIValues() { ReadBasicSetting(UISettings::values.enable_discord_presence); #endif ReadBasicSetting(UISettings::values.screenshot_resolution_factor); + { + const u16 srf = UISettings::values.screenshot_resolution_factor.GetValue(); + if (srf >= 1 && srf <= 10) { + LOG_WARNING( + Frontend, + "Migrating old screenshot resolution factor value of {} to new value of {}", + srf, srf * 100); + UISettings::values.screenshot_resolution_factor.SetValue(srf * 100); + } + } ReadUILayoutValues(); ReadUIGameListValues(); diff --git a/src/citra_qt/configuration/configure_enhancements.cpp b/src/citra_qt/configuration/configure_enhancements.cpp index 62afcbb77..8048c39cd 100644 --- a/src/citra_qt/configuration/configure_enhancements.cpp +++ b/src/citra_qt/configuration/configure_enhancements.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include +#include #include #include "citra_qt/configuration/configuration_shared.h" #include "citra_qt/configuration/configure_enhancements.h" @@ -11,6 +13,19 @@ #include "video_core/renderer_opengl/post_processing_opengl.h" #endif +static constexpr std::array RESOLUTION_FACTOR_VALUES = { + 0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, + 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, +}; + +static int ResolutionFactorToIndex(u32 value) { + const auto it = + std::find(RESOLUTION_FACTOR_VALUES.begin(), RESOLUTION_FACTOR_VALUES.end(), value); + return (it != RESOLUTION_FACTOR_VALUES.end()) + ? static_cast(std::distance(RESOLUTION_FACTOR_VALUES.begin(), it)) + : 0; +} + ConfigureEnhancements::ConfigureEnhancements(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); @@ -42,15 +57,20 @@ ConfigureEnhancements::~ConfigureEnhancements() = default; void ConfigureEnhancements::SetConfiguration() { if (!Settings::IsConfiguringGlobal()) { - ConfigurationShared::SetPerGameSetting(ui->resolution_factor_combobox, - &Settings::values.resolution_factor); + if (Settings::values.resolution_factor.UsingGlobal()) { + ui->resolution_factor_combobox->setCurrentIndex(ConfigurationShared::USE_GLOBAL_INDEX); + } else { + ui->resolution_factor_combobox->setCurrentIndex( + ResolutionFactorToIndex(Settings::values.resolution_factor.GetValue()) + + ConfigurationShared::USE_GLOBAL_OFFSET); + } ConfigurationShared::SetPerGameSetting(ui->texture_filter_combobox, &Settings::values.texture_filter); ConfigurationShared::SetHighlight(ui->widget_texture_filter, !Settings::values.texture_filter.UsingGlobal()); } else { ui->resolution_factor_combobox->setCurrentIndex( - Settings::values.resolution_factor.GetValue()); + ResolutionFactorToIndex(Settings::values.resolution_factor.GetValue())); ui->texture_filter_combobox->setCurrentIndex( static_cast(Settings::values.texture_filter.GetValue())); } @@ -109,8 +129,13 @@ void ConfigureEnhancements::RetranslateUI() { } void ConfigureEnhancements::ApplyConfiguration() { - ConfigurationShared::ApplyPerGameSetting(&Settings::values.resolution_factor, - ui->resolution_factor_combobox); + ConfigurationShared::ApplyPerGameSetting( + &Settings::values.resolution_factor, ui->resolution_factor_combobox, [](s32 index) -> s32 { + if (index >= 0 && index < static_cast(RESOLUTION_FACTOR_VALUES.size())) { + return static_cast(RESOLUTION_FACTOR_VALUES[index]); + } + return 0; + }); Settings::values.render_3d = static_cast(ui->render_3d_combobox->currentIndex()); Settings::values.swap_eyes_3d = ui->swap_eyes_3d->isChecked(); @@ -187,7 +212,8 @@ void ConfigureEnhancements::SetupPerGameUI() { ConfigurationShared::SetColoredComboBox( ui->resolution_factor_combobox, ui->widget_resolution, - static_cast(Settings::values.resolution_factor.GetValue(true))); + ResolutionFactorToIndex( + static_cast(Settings::values.resolution_factor.GetValue(true)))); ConfigurationShared::SetColoredComboBox( ui->texture_filter_combobox, ui->widget_texture_filter, diff --git a/src/citra_qt/configuration/configure_enhancements.ui b/src/citra_qt/configuration/configure_enhancements.ui index dc3c3deaf..27a790a95 100644 --- a/src/citra_qt/configuration/configure_enhancements.ui +++ b/src/citra_qt/configuration/configure_enhancements.ui @@ -51,13 +51,23 @@ - - Auto (Window Size) + + Auto (Window Size) + + + + + 0.5x Native (200x120) + + + + + Native (400x240) - Native (400x240) + 1.5x Native (600x360) @@ -65,41 +75,81 @@ 2x Native (800x480) + + + 2.5x Native (1000x600) + + 3x Native (1200x720) + + + 3.5x Native (1400x840) + + 4x Native (1600x960) + + + 4.5x Native (1800x1080) + + 5x Native (2000x1200) + + + 5.5x Native (2200x1320) + + 6x Native (2400x1440) + + + 6.5x Native (2600x1560) + + 7x Native (2800x1680) + + + 7.5x Native (3000x1800) + + 8x Native (3200x1920) + + + 8.5x Native (3400x2040) + + 9x Native (3600x2160) + + + 9.5x Native (3800x2280) + + 10x Native (4000x2400) diff --git a/src/common/settings.h b/src/common/settings.h index 90922bcff..059a23ea6 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -529,7 +529,7 @@ struct Values { SwitchableSetting use_display_refresh_rate_detection{ true, Keys::use_display_refresh_rate_detection}; Setting use_shader_jit{true, Keys::use_shader_jit}; - SwitchableSetting resolution_factor{1, 0, 10, Keys::resolution_factor}; + SwitchableSetting resolution_factor{100, 0, 1000, Keys::resolution_factor}; SwitchableSetting use_integer_scaling{false, Keys::use_integer_scaling}; SwitchableSetting frame_limit{100, 0, 1000, Keys::frame_limit}; SwitchableSetting turbo_limit{200, 0, 1000, Keys::turbo_limit}; diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index 918c1454f..3a36cd57d 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp @@ -375,7 +375,7 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height, bool is_swapped, bool FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary, bool is_portrait) { u32 width, height, gap; - gap = (int)(Settings::values.screen_gap.GetValue()) * res_scale; + gap = (Settings::values.screen_gap.GetValue() * res_scale) / 100; FramebufferLayout layout; if (is_portrait) { @@ -395,18 +395,18 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar break; case Settings::PortraitLayoutOption::PortraitTopFullWidth: - width = Core::kScreenTopWidth * res_scale; + width = (Core::kScreenTopWidth * res_scale) / 100; // clang-format off - height = (static_cast(Core::kScreenTopHeight + Core::kScreenBottomHeight * 1.25) * - res_scale) + gap; + height = (static_cast(Core::kScreenTopHeight + Core::kScreenBottomHeight * 1.25f) * + res_scale) / 100 + gap; // clang-format on layout = PortraitTopFullFrameLayout(width, height, Settings::values.swap_screen.GetValue(), Settings::values.upright_screen.GetValue()); break; case Settings::PortraitLayoutOption::PortraitOriginal: - width = Core::kScreenTopWidth * res_scale; - height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale; + width = (Core::kScreenTopWidth * res_scale) / 100; + height = ((Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale) / 100; layout = PortraitOriginalLayout(width, height, Settings::values.swap_screen.GetValue()); break; } @@ -428,11 +428,11 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar case Settings::LayoutOption::SingleScreen: { const bool swap_screens = is_secondary || Settings::values.swap_screen.GetValue(); if (swap_screens) { - width = Core::kScreenBottomWidth * res_scale; - height = Core::kScreenBottomHeight * res_scale; + width = (Core::kScreenBottomWidth * res_scale) / 100; + height = (Core::kScreenBottomHeight * res_scale) / 100; } else { - width = Core::kScreenTopWidth * res_scale; - height = Core::kScreenTopHeight * res_scale; + width = (Core::kScreenTopWidth * res_scale) / 100; + height = (Core::kScreenTopHeight * res_scale) / 100; } if (Settings::values.upright_screen.GetValue()) { std::swap(width, height); @@ -459,11 +459,11 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar Settings::values.small_screen_position.GetValue() == Settings::SmallScreenPosition::BelowLarge) { // vertical, so height is sum of heights, width is larger of widths - width = std::max(largeWidth, smallWidth) * res_scale; - height = (largeHeight + smallHeight) * res_scale + gap; + width = (static_cast(std::max(largeWidth, smallWidth)) * res_scale) / 100; + height = ((largeHeight + smallHeight) * res_scale) / 100 + gap; } else { - width = (largeWidth + smallWidth) * res_scale + gap; - height = std::max(largeHeight, smallHeight) * res_scale; + width = ((largeWidth + smallWidth) * res_scale) / 100 + gap; + height = (static_cast(std::max(largeHeight, smallHeight)) * res_scale) / 100; } if (Settings::values.upright_screen.GetValue()) { @@ -476,8 +476,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar break; } case Settings::LayoutOption::SideScreen: - width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale + gap; - height = Core::kScreenTopHeight * res_scale; + width = ((Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale) / 100 + gap; + height = (Core::kScreenTopHeight * res_scale) / 100; if (Settings::values.upright_screen.GetValue()) { std::swap(width, height); @@ -487,7 +487,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar Settings::SmallScreenPosition::MiddleRight); break; case Settings::LayoutOption::HybridScreen: - height = Core::kScreenTopHeight * res_scale; + height = (Core::kScreenTopHeight * res_scale) / 100; if (Settings::values.swap_screen.GetValue()) { width = Core::kScreenBottomWidth; @@ -495,7 +495,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar width = Core::kScreenTopWidth; } // 2.25f comes from HybridScreenLayout's scale_factor value. - width = static_cast((width + (Core::kScreenTopWidth / 2.25f)) * res_scale); + width = static_cast((width + (Core::kScreenTopWidth / 2.25f)) * res_scale) / 100; if (Settings::values.upright_screen.GetValue()) { std::swap(width, height); @@ -506,8 +506,8 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar break; case Settings::LayoutOption::Default: default: - width = Core::kScreenTopWidth * res_scale; - height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale + gap; + width = (Core::kScreenTopWidth * res_scale) / 100; + height = ((Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale) / 100 + gap; if (Settings::values.upright_screen.GetValue()) { std::swap(width, height); diff --git a/src/video_core/rasterizer_cache/framebuffer_base.h b/src/video_core/rasterizer_cache/framebuffer_base.h index 2f2545849..70cdd2474 100644 --- a/src/video_core/rasterizer_cache/framebuffer_base.h +++ b/src/video_core/rasterizer_cache/framebuffer_base.h @@ -69,7 +69,7 @@ public: Common::Rectangle surfaces_rect) : res_cache{res_cache_}, fb{fb_} { const u32 res_scale = fb->Scale(); - const u32 height = surfaces_rect.GetHeight() / res_scale; + const u32 height = (surfaces_rect.GetHeight() * 100) / res_scale; // Determine the draw rectangle (render area + scissor) Common::Rectangle viewport_rect = regs.GetViewportRect(); @@ -77,45 +77,53 @@ public: viewport_rect = viewport_rect.VerticalMirror(height); } - draw_rect.left = - std::clamp(static_cast(surfaces_rect.left) + viewport_rect.left * res_scale, - surfaces_rect.left, surfaces_rect.right); - draw_rect.top = - std::clamp(static_cast(surfaces_rect.bottom) + viewport_rect.top * res_scale, - surfaces_rect.bottom, surfaces_rect.top); - draw_rect.right = - std::clamp(static_cast(surfaces_rect.left) + viewport_rect.right * res_scale, - surfaces_rect.left, surfaces_rect.right); + draw_rect.left = std::clamp(static_cast(surfaces_rect.left) + + (viewport_rect.left * res_scale) / 100, + surfaces_rect.left, surfaces_rect.right); + draw_rect.top = std::clamp(static_cast(surfaces_rect.bottom) + + (viewport_rect.top * res_scale) / 100, + surfaces_rect.bottom, surfaces_rect.top); + draw_rect.right = std::clamp(static_cast(surfaces_rect.left) + + (viewport_rect.right * res_scale) / 100, + surfaces_rect.left, surfaces_rect.right); draw_rect.bottom = std::clamp(static_cast(surfaces_rect.bottom) + - viewport_rect.bottom * res_scale, + (viewport_rect.bottom * res_scale) / 100, surfaces_rect.bottom, surfaces_rect.top); // Update viewport - viewport.x = static_cast(surfaces_rect.left) + viewport_rect.left * res_scale; - viewport.y = static_cast(surfaces_rect.bottom) + viewport_rect.bottom * res_scale; - viewport.width = static_cast(viewport_rect.GetWidth() * res_scale); - viewport.height = static_cast(viewport_rect.GetHeight() * res_scale); + viewport.x = static_cast(surfaces_rect.left) + (viewport_rect.left * res_scale) / 100; + viewport.y = + static_cast(surfaces_rect.bottom) + (viewport_rect.bottom * res_scale) / 100; + viewport.width = static_cast((viewport_rect.GetWidth() * res_scale) / 100); + viewport.height = static_cast((viewport_rect.GetHeight() * res_scale) / 100); // Scissor checks are window-, not viewport-relative, which means that if the cached texture // sub-rect changes, the scissor bounds also need to be updated. - scissor_rect.left = static_cast(surfaces_rect.left + regs.scissor_test.x1 * res_scale); + scissor_rect.left = + static_cast(surfaces_rect.left + (regs.scissor_test.x1 * res_scale) / 100); scissor_rect.bottom = - static_cast(surfaces_rect.bottom + regs.scissor_test.y1 * res_scale); + static_cast(surfaces_rect.bottom + (regs.scissor_test.y1 * res_scale) / 100); // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when // scaling or doing multisampling. scissor_rect.right = - static_cast(surfaces_rect.left + (regs.scissor_test.x2 + 1) * res_scale); + static_cast(surfaces_rect.left + ((regs.scissor_test.x2 + 1) * res_scale) / 100); scissor_rect.top = - static_cast(surfaces_rect.bottom + (regs.scissor_test.y2 + 1) * res_scale); + static_cast(surfaces_rect.bottom + ((regs.scissor_test.y2 + 1) * res_scale) / 100); if (flip_rect) { - scissor_rect = scissor_rect.VerticalMirror(height); + scissor_rect = scissor_rect.VerticalMirror(surfaces_rect.GetHeight()); } } ~FramebufferHelper() { - const Common::Rectangle draw_rect_unscaled{draw_rect / fb->Scale()}; + const u32 scale = fb->Scale(); + const Common::Rectangle draw_rect_unscaled{ + (draw_rect.left * 100) / scale, + (draw_rect.top * 100) / scale, + (draw_rect.right * 100) / scale, + (draw_rect.bottom * 100) / scale, + }; const auto invalidate = [&](SurfaceId surface_id, u32 level) { const auto& surface = res_cache->GetSurface(surface_id); const SurfaceInterval interval = surface.GetSubRectInterval(draw_rect_unscaled, level); diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index 09d936020..69d82a944 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -213,7 +213,7 @@ bool RasterizerCache::AccelerateTextureCopy(const Pica::DisplayTransferConfig const SurfaceParams src_info = slot_surfaces[src_surface_id]; if (output_gap != 0 && - (output_width != src_info.BytesInPixels(src_rect.GetWidth() / src_info.res_scale) * + (output_width != src_info.BytesInPixels((src_rect.GetWidth() * 100) / src_info.res_scale) * (src_info.is_tiled ? 8 : 1) || output_gap % src_info.BytesInPixels(src_info.is_tiled ? 64 : 1) != 0)) { return false; @@ -221,10 +221,10 @@ bool RasterizerCache::AccelerateTextureCopy(const Pica::DisplayTransferConfig SurfaceParams dst_params = src_info; dst_params.addr = config.GetPhysicalOutputAddress(); - dst_params.width = src_rect.GetWidth() / src_info.res_scale; + dst_params.width = (src_rect.GetWidth() * 100) / src_info.res_scale; dst_params.stride = dst_params.width + src_info.PixelsInBytes(src_info.is_tiled ? output_gap / 8 : output_gap); - dst_params.height = src_rect.GetHeight() / src_info.res_scale; + dst_params.height = (src_rect.GetHeight() * 100) / src_info.res_scale; dst_params.res_scale = src_info.res_scale; dst_params.UpdateParams(); @@ -559,7 +559,7 @@ SurfaceId RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo params.levels = max_level + 1; params.is_tiled = true; params.pixel_format = PixelFormatFromTextureFormat(info.format); - params.res_scale = filter != Settings::TextureFilter::NoFilter ? resolution_scale_factor : 1; + params.res_scale = filter != Settings::TextureFilter::NoFilter ? resolution_scale_factor : 100; params.UpdateParams(); const u32 min_width = info.width >> max_level; @@ -616,7 +616,7 @@ typename T::Surface& RasterizerCache::GetTextureCube(const TextureCubeConfig& }; info.SetDefaultStride(); - u32 res_scale = 1; + u32 res_scale = 100; for (u32 i = 0; i < addresses.size(); i++) { if (!addresses[i]) { continue; diff --git a/src/video_core/rasterizer_cache/surface_params.cpp b/src/video_core/rasterizer_cache/surface_params.cpp index 74ae8205c..1510c091c 100644 --- a/src/video_core/rasterizer_cache/surface_params.cpp +++ b/src/video_core/rasterizer_cache/surface_params.cpp @@ -1,4 +1,4 @@ -// Copyright 2022 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -98,7 +98,9 @@ Common::Rectangle SurfaceParams::GetSubRect(const SurfaceParams& sub_surfac } Common::Rectangle SurfaceParams::GetScaledSubRect(const SurfaceParams& sub_surface) const { - return GetSubRect(sub_surface) * res_scale; + auto rect = GetSubRect(sub_surface); + return {(rect.left * res_scale) / 100, (rect.top * res_scale) / 100, + (rect.right * res_scale) / 100, (rect.bottom * res_scale) / 100}; } SurfaceParams SurfaceParams::FromInterval(SurfaceInterval interval) const { diff --git a/src/video_core/rasterizer_cache/surface_params.h b/src/video_core/rasterizer_cache/surface_params.h index 23e4db7e2..d97c329ec 100644 --- a/src/video_core/rasterizer_cache/surface_params.h +++ b/src/video_core/rasterizer_cache/surface_params.h @@ -1,4 +1,4 @@ -// Copyright 2022 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -64,11 +64,18 @@ public: } [[nodiscard]] u32 GetScaledWidth() const noexcept { - return width * res_scale; + return (width * res_scale) / 100; } [[nodiscard]] u32 GetScaledHeight() const noexcept { - return height * res_scale; + return (height * res_scale) / 100; + } + + /// Returns the scaled version of an unscaled rectangle using the 100-based res_scale + [[nodiscard]] Common::Rectangle ScaleRect( + const Common::Rectangle& rect) const noexcept { + return {(rect.left * res_scale) / 100, (rect.top * res_scale) / 100, + (rect.right * res_scale) / 100, (rect.bottom * res_scale) / 100}; } [[nodiscard]] Common::Rectangle GetRect(u32 level = 0) const noexcept { @@ -103,7 +110,7 @@ public: u32 height = 0; u32 stride = 0; u32 levels = 1; - u32 res_scale = 1; + u32 res_scale = 100; bool is_tiled = false; TextureType texture_type = TextureType::Texture2D; diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index e78ab9c91..af0b383be 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -20,13 +20,13 @@ RendererBase::~RendererBase() = default; u32 RendererBase::GetResolutionScaleFactor() { const auto graphics_api = Settings::values.graphics_api.GetValue(); if (graphics_api == Settings::GraphicsAPI::Software) { - // Software renderer always render at native resolution - return 1; + // Software renderer always renders at native resolution + return 100; } const u32 scale_factor = Settings::values.resolution_factor.GetValue(); return scale_factor != 0 ? scale_factor - : render_window.GetFramebufferLayout().GetScalingRatio(); + : render_window.GetFramebufferLayout().GetScalingRatio() * 100; } void RendererBase::UpdateCurrentFramebufferLayout(bool is_portrait_mode) { diff --git a/src/video_core/renderer_opengl/gl_blit_helper.cpp b/src/video_core/renderer_opengl/gl_blit_helper.cpp index 30a502316..5238eda89 100644 --- a/src/video_core/renderer_opengl/gl_blit_helper.cpp +++ b/src/video_core/renderer_opengl/gl_blit_helper.cpp @@ -265,7 +265,7 @@ void BlitHelper::FilterXbrz(Surface& surface, const VideoCore::TextureBlit& blit const OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); state.texture_units[0].texture_2d = surface.Handle(0); - glProgramUniform1f(xbrz_program.handle, 2, static_cast(surface.res_scale)); + glProgramUniform1f(xbrz_program.handle, 2, static_cast(surface.res_scale) / 100.0f); SetParams(xbrz_program, surface.RealExtent(false), blit.src_rect); Draw(xbrz_program, surface.Handle(), draw_fbo.handle, blit.dst_level, blit.dst_rect); } diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index f93b033ed..31a301e8e 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -328,7 +328,7 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceParams& param texture_type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; textures[0] = MakeHandle(target, width, height, levels, tuple, DebugName(false)); - if (res_scale != 1) { + if (res_scale != 100) { textures[1] = MakeHandle(target, GetScaledWidth(), GetScaledHeight(), levels, tuple, DebugName(true, false)); } @@ -349,7 +349,7 @@ Surface::Surface(TextureRuntime& runtime, const VideoCore::SurfaceBase& surface, material = mat; textures[0] = MakeHandle(target, mat->width, mat->height, levels, tuple, DebugName(false)); - if (res_scale != 1) { + if (res_scale != 100) { textures[1] = MakeHandle(target, mat->width, mat->height, levels, DEFAULT_TUPLE, DebugName(true, true)); } @@ -406,9 +406,9 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, .src_level = upload.texture_level, .dst_level = upload.texture_level, .src_rect = upload.texture_rect, - .dst_rect = upload.texture_rect * res_scale, + .dst_rect = ScaleRect(upload.texture_rect), }; - if (res_scale != 1 && !runtime->blit_helper.Filter(*this, blit)) { + if (res_scale != 100 && !runtime->blit_helper.Filter(*this, blit)) { BlitScale(blit, true); } } @@ -440,7 +440,7 @@ void Surface::UploadCustom(const VideoCore::Material* material, u32 level) { .src_rect = filter_rect, .dst_rect = filter_rect, }; - if (res_scale != 1 && !runtime->blit_helper.Filter(*this, blit)) { + if (res_scale != 100 && !runtime->blit_helper.Filter(*this, blit)) { BlitScale(blit, true); } for (u32 i = 1; i < VideoCore::MAX_MAPS; i++) { @@ -463,11 +463,11 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, glPixelStorei(GL_UNPACK_ROW_LENGTH, unscaled_width); // Scale down upscaled data before downloading it - if (res_scale != 1) { + if (res_scale != 100) { const VideoCore::TextureBlit blit = { .src_level = download.texture_level, .dst_level = download.texture_level, - .src_rect = download.texture_rect * res_scale, + .src_rect = ScaleRect(download.texture_rect), .dst_rect = download.texture_rect, }; BlitScale(blit, false); @@ -554,7 +554,7 @@ void Surface::Attach(GLenum target, u32 level, u32 layer, bool scaled) { } void Surface::ScaleUp(u32 new_scale) { - if (res_scale == new_scale || new_scale == 1) { + if (res_scale == new_scale || new_scale == 100) { return; } @@ -603,7 +603,7 @@ void Surface::BlitScale(const VideoCore::TextureBlit& blit, bool up_scale) { Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferParams& params, const Surface* color, const Surface* depth) : VideoCore::FramebufferParams{params}, - res_scale{color ? color->res_scale : (depth ? depth->res_scale : 1u)} { + res_scale{color ? color->res_scale : (depth ? depth->res_scale : 100u)} { if (shadow_rendering && !color) { return; @@ -624,9 +624,9 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa if (shadow_rendering) { glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, - color->width * res_scale); + (color->width * res_scale) / 100); glFramebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, - color->height * res_scale); + (color->height * res_scale) / 100); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.h b/src/video_core/renderer_opengl/gl_texture_runtime.h index 5fe7300a7..bbed4433d 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.h +++ b/src/video_core/renderer_opengl/gl_texture_runtime.h @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -182,7 +182,7 @@ public: } private: - u32 res_scale{1}; + u32 res_scale{100}; std::array attachments{}; OGLFramebuffer framebuffer; }; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index c8cb6c000..f4b024e31 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -556,10 +556,11 @@ void RendererOpenGL::DrawSingleScreen(const ScreenInfo& screen_info, float x, fl const u32 scale_factor = GetResolutionScaleFactor(); const GLuint sampler = samplers[Settings::values.filter_mode.GetValue()].handle; - glUniform4f(uniform_i_resolution, static_cast(screen_info.texture.width * scale_factor), - static_cast(screen_info.texture.height * scale_factor), - 1.0f / static_cast(screen_info.texture.width * scale_factor), - 1.0f / static_cast(screen_info.texture.height * scale_factor)); + glUniform4f(uniform_i_resolution, + static_cast((screen_info.texture.width * scale_factor) / 100.0f), + static_cast((screen_info.texture.height * scale_factor) / 100.0f), + 100.0f / static_cast(screen_info.texture.width * scale_factor), + 100.0f / static_cast(screen_info.texture.height * scale_factor)); glUniform4f(uniform_o_resolution, h, w, 1.0f / h, 1.0f / w); state.texture_units[0].texture_2d = screen_info.display_texture; state.texture_units[0].sampler = sampler; @@ -627,10 +628,10 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l, const u32 scale_factor = GetResolutionScaleFactor(); const GLuint sampler = samplers[Settings::values.filter_mode.GetValue()].handle; glUniform4f(uniform_i_resolution, - static_cast(screen_info_l.texture.width * scale_factor), - static_cast(screen_info_l.texture.height * scale_factor), - 1.0f / static_cast(screen_info_l.texture.width * scale_factor), - 1.0f / static_cast(screen_info_l.texture.height * scale_factor)); + static_cast((screen_info_l.texture.width * scale_factor) / 100.0f), + static_cast((screen_info_l.texture.height * scale_factor) / 100.0f), + 100.0f / static_cast(screen_info_l.texture.width * scale_factor), + 100.0f / static_cast(screen_info_l.texture.height * scale_factor)); glUniform4f(uniform_o_resolution, h, w, 1.0f / h, 1.0f / w); state.texture_units[0].texture_2d = screen_info_l.display_texture; state.texture_units[1].texture_2d = screen_info_r.display_texture; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 0a25c2036..53ae1461b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -783,10 +783,10 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float x, float y, float w, const u32 scale_factor = GetResolutionScaleFactor(); draw_info.i_resolution = - Common::MakeVec(static_cast(screen_info.texture.width * scale_factor), - static_cast(screen_info.texture.height * scale_factor), - 1.0f / static_cast(screen_info.texture.width * scale_factor), - 1.0f / static_cast(screen_info.texture.height * scale_factor)); + Common::MakeVec(static_cast((screen_info.texture.width * scale_factor) / 100.0f), + static_cast((screen_info.texture.height * scale_factor) / 100.0f), + 100.0f / static_cast(screen_info.texture.width * scale_factor), + 100.0f / static_cast(screen_info.texture.height * scale_factor)); draw_info.o_resolution = Common::MakeVec(h, w, 1.0f / h, 1.0f / w); draw_info.screen_id_l = screen_id; @@ -855,10 +855,10 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, fl const u32 scale_factor = GetResolutionScaleFactor(); draw_info.i_resolution = - Common::MakeVec(static_cast(screen_info_l.texture.width * scale_factor), - static_cast(screen_info_l.texture.height * scale_factor), - 1.0f / static_cast(screen_info_l.texture.width * scale_factor), - 1.0f / static_cast(screen_info_l.texture.height * scale_factor)); + Common::MakeVec(static_cast((screen_info_l.texture.width * scale_factor) / 100.0f), + static_cast((screen_info_l.texture.height * scale_factor) / 100.0f), + 100.0f / static_cast(screen_info_l.texture.width * scale_factor), + 100.0f / static_cast(screen_info_l.texture.height * scale_factor)); draw_info.o_resolution = Common::MakeVec(h, w, 1.0f / h, 1.0f / w); draw_info.screen_id_l = screen_id_l; draw_info.screen_id_r = screen_id_r; diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.cpp b/src/video_core/renderer_vulkan/vk_blit_helper.cpp index 9982948b3..3c24c0238 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_helper.cpp @@ -759,7 +759,7 @@ void BlitHelper::FilterPass(Surface& surface, vk::Pipeline pipeline, vk::Pipelin }, }; renderpass_cache.BeginRendering(render_pass); - const float src_scale = static_cast(surface.GetResScale()); + const float src_scale = static_cast(surface.GetResScale()) / 100.0f; // Calculate normalized texture coordinates like OpenGL does const auto src_extent = surface.RealExtent(false); // Get unscaled texture extent const float tex_scale_x = @@ -845,7 +845,7 @@ void BlitHelper::FilterPassThreeTextures(Surface& surface, vk::Pipeline pipeline }; renderpass_cache.BeginRendering(render_pass); - const float src_scale = static_cast(surface.GetResScale()); + const float src_scale = static_cast(surface.GetResScale()) / 100.0f; // Calculate normalized texture coordinates like OpenGL does const auto src_extent = surface.RealExtent(false); // Get unscaled texture extent const float tex_scale_x = diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index 52b7c6392..c916ad863 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -766,14 +766,14 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceParams& param traits.aspect, need_format_list, DebugName(false)); raw_images[num_images++] = handles[Type::Base].image; - if (res_scale != 1) { + if (res_scale != 100) { handles[Type::Scaled].Create(GetScaledWidth(), GetScaledHeight(), levels, texture_type, format, usage, flags, traits.aspect, need_format_list, DebugName(true)); raw_images[num_images++] = handles[Type::Scaled].image; } - current = res_scale != 1 ? Type::Scaled : Type::Base; + current = res_scale != 100 ? Type::Scaled : Type::Base; runtime.renderpass_cache.EndRendering(); scheduler.Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { @@ -810,7 +810,7 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceBase& surface flags, traits.aspect, false, debug_name); raw_images[num_images++] = handles[Type::Base].image; - if (res_scale != 1) { + if (res_scale != 100) { handles[Type::Scaled].Create(mat->width, mat->height, levels, texture_type, vk::Format::eR8G8B8A8Unorm, traits.usage, flags, traits.aspect, false, debug_name); @@ -822,7 +822,7 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceBase& surface raw_images[num_images++] = handles[Type::Custom].image; } - current = res_scale != 1 ? Type::Scaled : Type::Base; + current = res_scale != 100 ? Type::Scaled : Type::Base; runtime.renderpass_cache.EndRendering(); scheduler.Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { @@ -910,14 +910,14 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, runtime.upload_buffer.Commit(staging.size); - if (res_scale != 1) { + if (res_scale != 100) { ASSERT_MSG(handles[Type::Scaled], "Scaled allocation missing during upload"); const VideoCore::TextureBlit blit = { .src_level = upload.texture_level, .dst_level = upload.texture_level, .src_rect = upload.texture_rect, - .dst_rect = upload.texture_rect * res_scale, + .dst_rect = ScaleRect(upload.texture_rect), }; if ((type != SurfaceType::Color && type != SurfaceType::Texture) || !runtime.blit_helper.Filter(*this, blit)) { @@ -1013,11 +1013,11 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, return; } - if (res_scale != 1) { + if (res_scale != 100) { const VideoCore::TextureBlit blit = { .src_level = download.texture_level, .dst_level = download.texture_level, - .src_rect = download.texture_rect * res_scale, + .src_rect = ScaleRect(download.texture_rect), .dst_rect = download.texture_rect, }; @@ -1086,7 +1086,7 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, } void Surface::ScaleUp(u32 new_scale) { - if (res_scale == new_scale || new_scale == 1) { + if (res_scale == new_scale || new_scale == 100) { return; } @@ -1437,7 +1437,7 @@ void Surface::BlitScale(const VideoCore::TextureBlit& blit, bool up_scale) { Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferParams& params, Surface* color, Surface* depth) : VideoCore::FramebufferParams{params}, instance{runtime.GetInstance()}, - res_scale{color ? color->res_scale : (depth ? depth->res_scale : 1u)} { + res_scale{color ? color->res_scale : (depth ? depth->res_scale : 100u)} { auto& renderpass_cache = runtime.GetRenderpassCache(); if (shadow_rendering && !color) { return; diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.h b/src/video_core/renderer_vulkan/vk_texture_runtime.h index 17ac89c91..1d39e1fd9 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.h +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.h @@ -305,7 +305,7 @@ public: formats(std::exchange( other.formats, {VideoCore::PixelFormat::Invalid, VideoCore::PixelFormat::Invalid})), width(std::exchange(other.width, 0)), height(std::exchange(other.height, 0)), - res_scale(std::exchange(other.res_scale, 1)) {} + res_scale(std::exchange(other.res_scale, 100)) {} Framebuffer& operator=(Framebuffer&& other) noexcept { VideoCore::FramebufferParams::operator=(std::move(other)); @@ -319,7 +319,7 @@ public: {VideoCore::PixelFormat::Invalid, VideoCore::PixelFormat::Invalid}); width = std::exchange(other.width, 0); height = std::exchange(other.height, 0); - res_scale = std::exchange(other.res_scale, 1); + res_scale = std::exchange(other.res_scale, 100); return *this; } @@ -364,7 +364,7 @@ private: VideoCore::PixelFormat::Invalid}; u32 width{}; u32 height{}; - u32 res_scale{1}; + u32 res_scale{100}; }; class Sampler {