diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index bc0743296..f83cf2454 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -125,9 +125,11 @@ void GPU::UpdateSettings(const Settings& old_settings) m_console_is_pal = System::IsPALRegion(); UpdateCRTCConfig(); } - - // Crop mode calls this, so recalculate the display area - UpdateCRTCDisplayParameters(); + else if (g_settings.display_crop_mode != old_settings.display_crop_mode) + { + // Crop mode calls this, so recalculate the display area + UpdateCRTCDisplayParameters(); + } if (g_settings.display_scaling != old_settings.display_scaling || g_settings.display_deinterlacing_mode != old_settings.display_deinterlacing_mode || @@ -154,16 +156,16 @@ void GPU::CPUClockChanged() UpdateCRTCConfig(); } +u32 GPU::GetResolutionScale() const +{ + return 1u; +} + void GPU::UpdateResolutionScale() { } -std::tuple GPU::GetEffectiveDisplayResolution(bool scaled /* = true */) -{ - return std::tie(m_crtc_state.display_vram_width, m_crtc_state.display_vram_height); -} - -std::tuple GPU::GetFullDisplayResolution(bool scaled /* = true */) +std::tuple GPU::GetFullDisplayResolution() const { return std::tie(m_crtc_state.display_width, m_crtc_state.display_height); } @@ -789,6 +791,8 @@ void GPU::UpdateCRTCDisplayParameters() // won't be broken when displayed. const u8 y_shift = BoolToUInt8(m_GPUSTAT.vertical_interlace && m_GPUSTAT.vertical_resolution); const u8 height_shift = m_force_progressive_scan ? y_shift : BoolToUInt8(m_GPUSTAT.vertical_interlace); + const u16 old_vram_width = m_crtc_state.display_vram_width; + const u16 old_vram_height = m_crtc_state.display_vram_height; // Determine screen size. cs.display_width = (cs.horizontal_visible_end - cs.horizontal_visible_start) / cs.dot_clock_divider; @@ -852,6 +856,9 @@ void GPU::UpdateCRTCDisplayParameters() std::min(cs.vertical_visible_end, std::max(vertical_display_start, cs.vertical_visible_start))) << height_shift; } + + if (cs.display_vram_width != old_vram_width || cs.display_vram_height != old_vram_height) + UpdateResolutionScale(); } TickCount GPU::GetPendingCRTCTicks() const diff --git a/src/core/gpu.h b/src/core/gpu.h index 5524376bf..3e67f5463 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -165,14 +165,14 @@ public: /// Recompile shaders/recreate framebuffers when needed. virtual void UpdateSettings(const Settings& old_settings); + /// Returns the current resolution scale. + virtual u32 GetResolutionScale() const; + /// Updates the resolution scale when it's set to automatic. virtual void UpdateResolutionScale(); - /// Returns the effective display resolution of the GPU. - virtual std::tuple GetEffectiveDisplayResolution(bool scaled = true); - /// Returns the full display resolution of the GPU, including padding. - virtual std::tuple GetFullDisplayResolution(bool scaled = true); + std::tuple GetFullDisplayResolution() const; float ComputeHorizontalFrequency() const; float ComputeVerticalFrequency() const; diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 92b4a3ba3..e59966258 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -425,13 +425,11 @@ void GPU_HW::UpdateSettings(const Settings& old_settings) if (m_resolution_scale != resolution_scale) { - Host::AddIconOSDMessage( - "ResolutionScaleChanged", ICON_FA_PAINT_BRUSH, - fmt::format(TRANSLATE_FS("GPU_HW", "Resolution scale set to {0}x (display {1}x{2}, VRAM {3}x{4})"), - resolution_scale, m_crtc_state.display_vram_width * resolution_scale, - resolution_scale * m_crtc_state.display_vram_height, VRAM_WIDTH * resolution_scale, - VRAM_HEIGHT * resolution_scale), - Host::OSD_INFO_DURATION); + Host::AddIconOSDMessage("ResolutionScaleChanged", ICON_FA_PAINT_BRUSH, + fmt::format(TRANSLATE_FS("GPU_HW", "Internal resolution set to {0}x ({1}x{2})."), + resolution_scale, m_crtc_state.display_width * resolution_scale, + resolution_scale * m_crtc_state.display_height), + Host::OSD_INFO_DURATION); } if (m_multisamples != multisamples || g_settings.gpu_per_sample_shading != old_settings.gpu_per_sample_shading) @@ -635,26 +633,37 @@ void GPU_HW::CheckSettings() u32 GPU_HW::CalculateResolutionScale() const { - const u32 max_resolution_scale = GetMaxResolutionScale(); - u32 scale; if (g_settings.gpu_resolution_scale != 0) { - scale = std::clamp(g_settings.gpu_resolution_scale, 1, max_resolution_scale); + scale = g_settings.gpu_resolution_scale; } else { - // Auto scaling. When the system is starting and all borders crop is enabled, the registers are zero, and - // display_height therefore is also zero. Use the default size from the region in this case. - const s32 height = (m_crtc_state.display_height != 0) ? - static_cast(m_crtc_state.display_height) : - (m_console_is_pal ? (PAL_VERTICAL_ACTIVE_END - PAL_VERTICAL_ACTIVE_START) : - (NTSC_VERTICAL_ACTIVE_END - NTSC_VERTICAL_ACTIVE_START)); - const s32 preferred_scale = - static_cast(std::ceil(static_cast(g_gpu_device->GetWindowHeight()) / height)); - VERBOSE_LOG("Height = {}, preferred scale = {}", height, preferred_scale); + // Auto scaling. + if (m_crtc_state.display_width == 0 || m_crtc_state.display_height == 0 || m_crtc_state.display_vram_width == 0 || + m_crtc_state.display_vram_height == 0 || m_GPUSTAT.display_disable) + { + // When the system is starting and all borders crop is enabled, the registers are zero, and + // display_height therefore is also zero. Keep the existing resolution until it updates. + scale = m_resolution_scale; + } + else + { + GSVector4i display_rect, draw_rect; + CalculateDrawRect(g_gpu_device->GetWindowWidth(), g_gpu_device->GetWindowHeight(), true, true, &display_rect, + &draw_rect); - scale = static_cast(std::clamp(preferred_scale, 1, max_resolution_scale)); + // We use the draw rect to determine scaling. This way we match the resolution as best we can, regardless of the + // anamorphic aspect ratio. + const s32 draw_width = draw_rect.width(); + const s32 draw_height = draw_rect.height(); + scale = static_cast( + std::ceil(std::max(static_cast(draw_width) / static_cast(m_crtc_state.display_vram_width), + static_cast(draw_height) / static_cast(m_crtc_state.display_vram_height)))); + VERBOSE_LOG("Draw Size = {}x{}, VRAM Size = {}x{}, Preferred Scale = {}", draw_width, draw_height, + m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, scale); + } } if (g_settings.gpu_downsample_mode == GPUDownsampleMode::Adaptive && scale > 1 && !Common::IsPow2(scale)) @@ -675,13 +684,16 @@ u32 GPU_HW::CalculateResolutionScale() const scale = new_scale; } - return scale; + return std::clamp(scale, 1, GetMaxResolutionScale()); +} + +u32 GPU_HW::GetResolutionScale() const +{ + return m_resolution_scale; } void GPU_HW::UpdateResolutionScale() { - GPU::UpdateResolutionScale(); - if (CalculateResolutionScale() != m_resolution_scale) UpdateSettings(g_settings); } @@ -746,18 +758,6 @@ void GPU_HW::SetTexPageChangedOnOverlap(const GSVector4i update_rect) } } -std::tuple GPU_HW::GetEffectiveDisplayResolution(bool scaled /* = true */) -{ - const u32 scale = scaled ? m_resolution_scale : 1u; - return std::make_tuple(m_crtc_state.display_vram_width * scale, m_crtc_state.display_vram_height * scale); -} - -std::tuple GPU_HW::GetFullDisplayResolution(bool scaled /* = true */) -{ - const u32 scale = scaled ? m_resolution_scale : 1u; - return std::make_tuple(m_crtc_state.display_width * scale, m_crtc_state.display_height * scale); -} - void GPU_HW::PrintSettingsToLog() { INFO_LOG("Resolution Scale: {} ({}x{}), maximum {}", m_resolution_scale, VRAM_WIDTH * m_resolution_scale, diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 1ada1e17f..80a5f45f8 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -65,9 +65,9 @@ public: void RestoreDeviceContext() override; void UpdateSettings(const Settings& old_settings) override; - void UpdateResolutionScale() override final; - std::tuple GetEffectiveDisplayResolution(bool scaled = true) override; - std::tuple GetFullDisplayResolution(bool scaled = true) override; + + u32 GetResolutionScale() const override; + void UpdateResolutionScale() override; void UpdateDisplay() override; diff --git a/src/core/host.cpp b/src/core/host.cpp index c0d80db8a..8e861fbca 100644 --- a/src/core/host.cpp +++ b/src/core/host.cpp @@ -344,6 +344,7 @@ void Host::UpdateDisplayWindow() const float f_height = static_cast(g_gpu_device->GetWindowHeight()); ImGuiManager::WindowResized(f_width, f_height); InputManager::SetDisplayWindowSize(f_width, f_height); + System::HostDisplayResized(); if (System::IsValid()) { diff --git a/src/core/imgui_overlays.cpp b/src/core/imgui_overlays.cpp index f41b0b8ba..08497c6d5 100644 --- a/src/core/imgui_overlays.cpp +++ b/src/core/imgui_overlays.cpp @@ -291,12 +291,12 @@ void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, float if (g_settings.display_show_resolution) { - // TODO: this seems wrong? - const auto [effective_width, effective_height] = g_gpu->GetEffectiveDisplayResolution(); + const u32 resolution_scale = g_gpu->GetResolutionScale(); + const auto [display_width, display_height] = g_gpu->GetFullDisplayResolution(); const bool interlaced = g_gpu->IsInterlacedDisplayEnabled(); const bool pal = g_gpu->IsInPALMode(); - text.format("{}x{} {} {}", effective_width, effective_height, pal ? "PAL" : "NTSC", - interlaced ? "Interlaced" : "Progressive"); + text.format("{}x{} {} {} [{}x]", display_width * resolution_scale, display_height * resolution_scale, + pal ? "PAL" : "NTSC", interlaced ? "Interlaced" : "Progressive", resolution_scale); DRAW_LINE(fixed_font, text, IM_COL32(255, 255, 255, 255)); } diff --git a/src/core/system.cpp b/src/core/system.cpp index f96009ebb..69f25df70 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -5718,6 +5718,7 @@ void System::ToggleSoftwareRendering() Settings::GetRendererDisplayName(new_renderer)), Host::OSD_QUICK_DURATION); RecreateGPU(new_renderer); + g_gpu->UpdateResolutionScale(); ResetPerformanceCounters(); } @@ -5753,6 +5754,7 @@ void System::HostDisplayResized() if (g_settings.gpu_widescreen_hack && g_settings.display_aspect_ratio == DisplayAspectRatio::MatchWindow) GTE::UpdateAspectRatio(); + g_gpu->RestoreDeviceContext(); g_gpu->UpdateResolutionScale(); } diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index 129e2298c..67b171d16 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -2005,7 +2005,12 @@ void EmuThread::updatePerformanceCounters() u32 render_height = 0; if (g_gpu) - std::tie(render_width, render_height) = g_gpu->GetEffectiveDisplayResolution(); + { + const u32 render_scale = g_gpu->GetResolutionScale(); + std::tie(render_width, render_height) = g_gpu->GetFullDisplayResolution(); + render_width *= render_scale; + render_height *= render_scale; + } if (render_api != m_last_render_api || hardware_renderer != m_last_hardware_renderer) {