mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-07 03:55:33 +00:00
GPU: Rewrite automatic resolution scaling
Make it play nice with rewind/runahead.
This commit is contained in:
parent
d812463649
commit
3ea26cc910
@ -1018,9 +1018,9 @@ void GPU::UpdateCRTCDisplayParameters()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((cs.display_vram_width != old_vram_width || cs.display_vram_height != old_vram_height) &&
|
if ((cs.display_vram_width != old_vram_width || cs.display_vram_height != old_vram_height) &&
|
||||||
g_settings.gpu_resolution_scale == 0)
|
g_settings.gpu_automatic_resolution_scale)
|
||||||
{
|
{
|
||||||
GPUBackend::QueueUpdateResolutionScale();
|
System::UpdateAutomaticResolutionScale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1980,6 +1980,38 @@ void GPU::QueuePresentCurrentFrame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 GPU::CalculateAutomaticResolutionScale() const
|
||||||
|
{
|
||||||
|
// Auto scaling.
|
||||||
|
// 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.
|
||||||
|
u32 scale = 1;
|
||||||
|
if (const WindowInfo& main_window_info = GPUThread::GetRenderWindowInfo();
|
||||||
|
!main_window_info.IsSurfaceless() && 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)
|
||||||
|
{
|
||||||
|
GSVector4i display_rect, draw_rect;
|
||||||
|
CalculateDrawRect(main_window_info.surface_width, main_window_info.surface_height, m_crtc_state.display_width,
|
||||||
|
m_crtc_state.display_height, m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||||
|
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, g_settings.display_rotation,
|
||||||
|
g_settings.display_alignment, g_settings.gpu_show_vram ? 1.0f : ComputePixelAspectRatio(),
|
||||||
|
g_settings.IsUsingIntegerDisplayScaling(), &display_rect, &draw_rect);
|
||||||
|
|
||||||
|
// 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<u32>(
|
||||||
|
std::ceil(std::max(static_cast<float>(draw_width) / static_cast<float>(m_crtc_state.display_vram_width),
|
||||||
|
static_cast<float>(draw_height) / static_cast<float>(m_crtc_state.display_vram_height))));
|
||||||
|
scale = std::min<u32>(scale, std::numeric_limits<decltype(g_settings.gpu_resolution_scale)>::max());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Truncate8(scale);
|
||||||
|
}
|
||||||
|
|
||||||
bool GPU::DumpVRAMToFile(const char* filename)
|
bool GPU::DumpVRAMToFile(const char* filename)
|
||||||
{
|
{
|
||||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||||
|
@ -230,6 +230,9 @@ public:
|
|||||||
// Queues the current frame for presentation. Should only be used with runahead.
|
// Queues the current frame for presentation. Should only be used with runahead.
|
||||||
void QueuePresentCurrentFrame();
|
void QueuePresentCurrentFrame();
|
||||||
|
|
||||||
|
/// Computes the effective resolution scale when it is set to automatic.
|
||||||
|
u8 CalculateAutomaticResolutionScale() const;
|
||||||
|
|
||||||
/// Helper function for computing the draw rectangle in a larger window.
|
/// Helper function for computing the draw rectangle in a larger window.
|
||||||
static void CalculateDrawRect(u32 window_width, u32 window_height, u32 crtc_display_width, u32 crtc_display_height,
|
static void CalculateDrawRect(u32 window_width, u32 window_height, u32 crtc_display_width, u32 crtc_display_height,
|
||||||
s32 display_origin_left, s32 display_origin_top, u32 display_vram_width,
|
s32 display_origin_left, s32 display_origin_top, u32 display_vram_width,
|
||||||
|
@ -398,20 +398,6 @@ bool GPUBackend::AllocateMemorySaveStates(std::span<System::MemorySaveState> sta
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPUBackend::QueueUpdateResolutionScale()
|
|
||||||
{
|
|
||||||
DebugAssert(!GPUThread::IsOnThread());
|
|
||||||
|
|
||||||
GPUThread::RunOnBackend(
|
|
||||||
[](GPUBackend* backend) {
|
|
||||||
Error error;
|
|
||||||
if (!backend->UpdateResolutionScale(&error)) [[unlikely]]
|
|
||||||
GPUThread::ReportFatalErrorAndShutdown(
|
|
||||||
fmt::format("Failed to update resolution scale: {}", error.GetDescription()));
|
|
||||||
},
|
|
||||||
false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUBackend::HandleCommand(const GPUThreadCommand* cmd)
|
void GPUBackend::HandleCommand(const GPUThreadCommand* cmd)
|
||||||
{
|
{
|
||||||
switch (cmd->type)
|
switch (cmd->type)
|
||||||
@ -837,7 +823,6 @@ public:
|
|||||||
bool UpdateSettings(const GPUSettings& old_settings, Error* error) override;
|
bool UpdateSettings(const GPUSettings& old_settings, Error* error) override;
|
||||||
|
|
||||||
u32 GetResolutionScale() const override;
|
u32 GetResolutionScale() const override;
|
||||||
bool UpdateResolutionScale(Error* error) override;
|
|
||||||
|
|
||||||
void RestoreDeviceContext() override;
|
void RestoreDeviceContext() override;
|
||||||
void FlushRender() override;
|
void FlushRender() override;
|
||||||
@ -891,11 +876,6 @@ u32 GPUNullBackend::GetResolutionScale() const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPUNullBackend::UpdateResolutionScale(Error* error)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUNullBackend::RestoreDeviceContext()
|
void GPUNullBackend::RestoreDeviceContext()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,6 @@ public:
|
|||||||
|
|
||||||
static bool AllocateMemorySaveStates(std::span<System::MemorySaveState> states, Error* error);
|
static bool AllocateMemorySaveStates(std::span<System::MemorySaveState> states, Error* error);
|
||||||
|
|
||||||
static void QueueUpdateResolutionScale();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GPUBackend(GPUPresenter& presenter);
|
GPUBackend(GPUPresenter& presenter);
|
||||||
virtual ~GPUBackend();
|
virtual ~GPUBackend();
|
||||||
@ -86,9 +84,6 @@ public:
|
|||||||
/// Returns the current resolution scale.
|
/// Returns the current resolution scale.
|
||||||
virtual u32 GetResolutionScale() const = 0;
|
virtual u32 GetResolutionScale() const = 0;
|
||||||
|
|
||||||
/// Updates the resolution scale when it's set to automatic.
|
|
||||||
virtual bool UpdateResolutionScale(Error* error) = 0;
|
|
||||||
|
|
||||||
// Graphics API state reset/restore - call when drawing the UI etc.
|
// Graphics API state reset/restore - call when drawing the UI etc.
|
||||||
// TODO: replace with "invalidate cached state"
|
// TODO: replace with "invalidate cached state"
|
||||||
virtual void RestoreDeviceContext() = 0;
|
virtual void RestoreDeviceContext() = 0;
|
||||||
|
@ -726,40 +726,7 @@ void GPU_HW::CheckSettings()
|
|||||||
|
|
||||||
u32 GPU_HW::CalculateResolutionScale() const
|
u32 GPU_HW::CalculateResolutionScale() const
|
||||||
{
|
{
|
||||||
u32 scale;
|
u32 scale = g_gpu_settings.gpu_resolution_scale;
|
||||||
if (g_gpu_settings.gpu_resolution_scale != 0)
|
|
||||||
{
|
|
||||||
scale = g_gpu_settings.gpu_resolution_scale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Auto scaling.
|
|
||||||
if (m_presenter.GetDisplayWidth() == 0 || m_presenter.GetDisplayHeight() == 0 ||
|
|
||||||
m_presenter.GetDisplayVRAMWidth() == 0 || m_presenter.GetDisplayVRAMHeight() == 0 ||
|
|
||||||
!m_presenter.HasDisplayTexture() || !g_gpu_device->HasMainSwapChain())
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
m_presenter.CalculateDrawRect(g_gpu_device->GetMainSwapChain()->GetWidth(),
|
|
||||||
g_gpu_device->GetMainSwapChain()->GetHeight(), true, true, &display_rect,
|
|
||||||
&draw_rect);
|
|
||||||
|
|
||||||
// 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<u32>(
|
|
||||||
std::ceil(std::max(static_cast<float>(draw_width) / static_cast<float>(m_presenter.GetDisplayVRAMWidth()),
|
|
||||||
static_cast<float>(draw_height) / static_cast<float>(m_presenter.GetDisplayVRAMHeight()))));
|
|
||||||
VERBOSE_LOG("Draw Size = {}x{}, VRAM Size = {}x{}, Preferred Scale = {}", draw_width, draw_height,
|
|
||||||
m_presenter.GetDisplayVRAMWidth(), m_presenter.GetDisplayVRAMHeight(), scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_gpu_settings.gpu_downsample_mode == GPUDownsampleMode::Adaptive && scale > 1 && !Common::IsPow2(scale))
|
if (g_gpu_settings.gpu_downsample_mode == GPUDownsampleMode::Adaptive && scale > 1 && !Common::IsPow2(scale))
|
||||||
{
|
{
|
||||||
@ -782,14 +749,6 @@ u32 GPU_HW::CalculateResolutionScale() const
|
|||||||
return std::clamp<u32>(scale, 1, GetMaxResolutionScale());
|
return std::clamp<u32>(scale, 1, GetMaxResolutionScale());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU_HW::UpdateResolutionScale(Error* error)
|
|
||||||
{
|
|
||||||
if (CalculateResolutionScale() == m_resolution_scale)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return UpdateSettings(g_gpu_settings, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
GPUDownsampleMode GPU_HW::GetDownsampleMode(u32 resolution_scale) const
|
GPUDownsampleMode GPU_HW::GetDownsampleMode(u32 resolution_scale) const
|
||||||
{
|
{
|
||||||
return (resolution_scale == 1) ? GPUDownsampleMode::Disabled : g_gpu_settings.gpu_downsample_mode;
|
return (resolution_scale == 1) ? GPUDownsampleMode::Disabled : g_gpu_settings.gpu_downsample_mode;
|
||||||
|
@ -74,8 +74,6 @@ public:
|
|||||||
bool UpdateSettings(const GPUSettings& old_settings, Error* error) override;
|
bool UpdateSettings(const GPUSettings& old_settings, Error* error) override;
|
||||||
void UpdatePostProcessingSettings(bool force_reload) override;
|
void UpdatePostProcessingSettings(bool force_reload) override;
|
||||||
|
|
||||||
bool UpdateResolutionScale(Error* error) override;
|
|
||||||
|
|
||||||
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color, bool interlaced_rendering, u8 active_line_lsb) override;
|
void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color, bool interlaced_rendering, u8 active_line_lsb) override;
|
||||||
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
|
void ReadVRAM(u32 x, u32 y, u32 width, u32 height) override;
|
||||||
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) override;
|
||||||
|
@ -1004,8 +1004,7 @@ bool GPUPresenter::ApplyChromaSmoothing()
|
|||||||
void GPUPresenter::CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio, bool apply_alignment,
|
void GPUPresenter::CalculateDrawRect(s32 window_width, s32 window_height, bool apply_aspect_ratio, bool apply_alignment,
|
||||||
GSVector4i* display_rect, GSVector4i* draw_rect) const
|
GSVector4i* display_rect, GSVector4i* draw_rect) const
|
||||||
{
|
{
|
||||||
const bool integer_scale = (g_gpu_settings.display_scaling == DisplayScalingMode::NearestInteger ||
|
const bool integer_scale = g_gpu_settings.IsUsingIntegerDisplayScaling();
|
||||||
g_gpu_settings.display_scaling == DisplayScalingMode::BilinearInteger);
|
|
||||||
const bool show_vram = g_gpu_settings.gpu_show_vram;
|
const bool show_vram = g_gpu_settings.gpu_show_vram;
|
||||||
const u32 display_width = show_vram ? VRAM_WIDTH : m_display_width;
|
const u32 display_width = show_vram ? VRAM_WIDTH : m_display_width;
|
||||||
const u32 display_height = show_vram ? VRAM_HEIGHT : m_display_height;
|
const u32 display_height = show_vram ? VRAM_HEIGHT : m_display_height;
|
||||||
|
@ -65,11 +65,6 @@ void GPU_SW::ClearVRAM()
|
|||||||
std::memset(g_gpu_clut, 0, sizeof(g_gpu_clut));
|
std::memset(g_gpu_clut, 0, sizeof(g_gpu_clut));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU_SW::UpdateResolutionScale(Error* error)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_SW::LoadState(const GPUBackendLoadStateCommand* cmd)
|
void GPU_SW::LoadState(const GPUBackendLoadStateCommand* cmd)
|
||||||
{
|
{
|
||||||
std::memcpy(g_vram, cmd->vram_data, sizeof(g_vram));
|
std::memcpy(g_vram, cmd->vram_data, sizeof(g_vram));
|
||||||
|
@ -46,8 +46,6 @@ public:
|
|||||||
|
|
||||||
void ClearVRAM() override;
|
void ClearVRAM() override;
|
||||||
|
|
||||||
bool UpdateResolutionScale(Error* error) override;
|
|
||||||
|
|
||||||
void LoadState(const GPUBackendLoadStateCommand* cmd) override;
|
void LoadState(const GPUBackendLoadStateCommand* cmd) override;
|
||||||
|
|
||||||
bool AllocateMemorySaveState(System::MemorySaveState& mss, Error* error) override;
|
bool AllocateMemorySaveState(System::MemorySaveState& mss, Error* error) override;
|
||||||
|
@ -1287,13 +1287,6 @@ void GPUThread::DisplayWindowResizedOnThread()
|
|||||||
Internal::PresentFrameAndRestoreContext();
|
Internal::PresentFrameAndRestoreContext();
|
||||||
Internal::PresentFrameAndRestoreContext();
|
Internal::PresentFrameAndRestoreContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_gpu_settings.gpu_resolution_scale == 0)
|
|
||||||
{
|
|
||||||
Error error;
|
|
||||||
if (!s_state.gpu_backend->UpdateResolutionScale(&error)) [[unlikely]]
|
|
||||||
ReportFatalErrorAndShutdown(fmt::format("Failed to update resolution scale: {}", error.GetDescription()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +199,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro
|
|||||||
.value_or(DEFAULT_GPU_RENDERER);
|
.value_or(DEFAULT_GPU_RENDERER);
|
||||||
gpu_adapter = si.GetStringValue("GPU", "Adapter", "");
|
gpu_adapter = si.GetStringValue("GPU", "Adapter", "");
|
||||||
gpu_resolution_scale = static_cast<u8>(si.GetUIntValue("GPU", "ResolutionScale", 1u));
|
gpu_resolution_scale = static_cast<u8>(si.GetUIntValue("GPU", "ResolutionScale", 1u));
|
||||||
|
gpu_automatic_resolution_scale = (gpu_resolution_scale == 0);
|
||||||
gpu_multisamples = static_cast<u8>(si.GetUIntValue("GPU", "Multisamples", 1u));
|
gpu_multisamples = static_cast<u8>(si.GetUIntValue("GPU", "Multisamples", 1u));
|
||||||
gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false);
|
gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false);
|
||||||
gpu_disable_shader_cache = si.GetBoolValue("GPU", "DisableShaderCache", false);
|
gpu_disable_shader_cache = si.GetBoolValue("GPU", "DisableShaderCache", false);
|
||||||
@ -972,6 +973,7 @@ void Settings::FixIncompatibleSettings(const SettingsInterface& si, bool display
|
|||||||
g_settings.enable_8mb_ram = false;
|
g_settings.enable_8mb_ram = false;
|
||||||
g_settings.gpu_resolution_scale = 1;
|
g_settings.gpu_resolution_scale = 1;
|
||||||
g_settings.gpu_multisamples = 1;
|
g_settings.gpu_multisamples = 1;
|
||||||
|
g_settings.gpu_automatic_resolution_scale = false;
|
||||||
g_settings.gpu_per_sample_shading = false;
|
g_settings.gpu_per_sample_shading = false;
|
||||||
g_settings.gpu_true_color = false;
|
g_settings.gpu_true_color = false;
|
||||||
g_settings.gpu_scaled_dithering = false;
|
g_settings.gpu_scaled_dithering = false;
|
||||||
|
@ -102,6 +102,7 @@ struct GPUSettings
|
|||||||
bool gpu_disable_raster_order_views : 1 = false;
|
bool gpu_disable_raster_order_views : 1 = false;
|
||||||
bool gpu_disable_compute_shaders : 1 = false;
|
bool gpu_disable_compute_shaders : 1 = false;
|
||||||
bool gpu_disable_compressed_textures : 1 = false;
|
bool gpu_disable_compressed_textures : 1 = false;
|
||||||
|
bool gpu_automatic_resolution_scale : 1 = false;
|
||||||
bool gpu_per_sample_shading : 1 = false;
|
bool gpu_per_sample_shading : 1 = false;
|
||||||
bool gpu_true_color : 1 = true;
|
bool gpu_true_color : 1 = true;
|
||||||
bool gpu_scaled_dithering : 1 = true;
|
bool gpu_scaled_dithering : 1 = true;
|
||||||
@ -210,6 +211,11 @@ struct GPUSettings
|
|||||||
|
|
||||||
ALWAYS_INLINE bool IsUsingSoftwareRenderer() const { return (gpu_renderer == GPURenderer::Software); }
|
ALWAYS_INLINE bool IsUsingSoftwareRenderer() const { return (gpu_renderer == GPURenderer::Software); }
|
||||||
ALWAYS_INLINE bool IsUsingAccurateBlending() const { return (gpu_accurate_blending && !gpu_true_color); }
|
ALWAYS_INLINE bool IsUsingAccurateBlending() const { return (gpu_accurate_blending && !gpu_true_color); }
|
||||||
|
ALWAYS_INLINE bool IsUsingIntegerDisplayScaling() const
|
||||||
|
{
|
||||||
|
return (display_scaling == DisplayScalingMode::NearestInteger ||
|
||||||
|
display_scaling == DisplayScalingMode::BilinearInteger);
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool UsingPGXPCPUMode() const { return gpu_pgxp_enable && gpu_pgxp_cpu; }
|
ALWAYS_INLINE bool UsingPGXPCPUMode() const { return gpu_pgxp_enable && gpu_pgxp_cpu; }
|
||||||
ALWAYS_INLINE bool UsingPGXPDepthBuffer() const { return gpu_pgxp_enable && gpu_pgxp_depth_buffer; }
|
ALWAYS_INLINE bool UsingPGXPDepthBuffer() const { return gpu_pgxp_enable && gpu_pgxp_depth_buffer; }
|
||||||
|
@ -1219,6 +1219,10 @@ void System::LoadSettings(bool display_osd_messages)
|
|||||||
(g_settings.disable_all_enhancements ||
|
(g_settings.disable_all_enhancements ||
|
||||||
Host::Internal::GetBaseSettingsLayer()->GetBoolValue("Main", "DisableAllEnhancements", false));
|
Host::Internal::GetBaseSettingsLayer()->GetBoolValue("Main", "DisableAllEnhancements", false));
|
||||||
|
|
||||||
|
// Fix up automatic resolution scale, yuck.
|
||||||
|
if (g_settings.gpu_automatic_resolution_scale && IsValid())
|
||||||
|
g_settings.gpu_resolution_scale = g_gpu.CalculateAutomaticResolutionScale();
|
||||||
|
|
||||||
Settings::UpdateLogConfig(si);
|
Settings::UpdateLogConfig(si);
|
||||||
Host::LoadSettings(si, lock);
|
Host::LoadSettings(si, lock);
|
||||||
InputManager::ReloadSources(controller_si, lock);
|
InputManager::ReloadSources(controller_si, lock);
|
||||||
@ -1934,6 +1938,7 @@ bool System::Initialize(std::unique_ptr<CDImage> disc, DiscRegion disc_region, b
|
|||||||
PCDrv::Initialize();
|
PCDrv::Initialize();
|
||||||
|
|
||||||
UpdateGTEAspectRatio();
|
UpdateGTEAspectRatio();
|
||||||
|
UpdateAutomaticResolutionScale();
|
||||||
UpdateThrottlePeriod();
|
UpdateThrottlePeriod();
|
||||||
UpdateMemorySaveStateSettings();
|
UpdateMemorySaveStateSettings();
|
||||||
|
|
||||||
@ -2592,7 +2597,7 @@ void System::ClearMemorySaveStates(bool reallocate_resources, bool recycle_textu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// immediately save a rewind state next frame
|
// immediately save a rewind state next frame
|
||||||
s_state.rewind_save_counter = (s_state.rewind_save_frequency > 0) ? 0 : -1;
|
s_state.rewind_save_counter = (s_state.rewind_save_frequency >= 0) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::FreeMemoryStateStorage(bool release_memory, bool release_textures, bool recycle_textures)
|
void System::FreeMemoryStateStorage(bool release_memory, bool release_textures, bool recycle_textures)
|
||||||
@ -4220,8 +4225,8 @@ void System::UpdateRunningGame(const std::string& path, CDImage* image, bool boo
|
|||||||
|
|
||||||
UpdateRichPresence(booting);
|
UpdateRichPresence(booting);
|
||||||
|
|
||||||
FullscreenUI::OnRunningGameChanged(s_state.running_game_path, s_state.running_game_serial,
|
FullscreenUI::OnRunningGameChanged(s_state.running_game_path, s_state.running_game_serial, s_state.running_game_title,
|
||||||
s_state.running_game_title, s_state.running_game_hash);
|
s_state.running_game_hash);
|
||||||
|
|
||||||
Host::OnGameChanged(s_state.running_game_path, s_state.running_game_serial, s_state.running_game_title,
|
Host::OnGameChanged(s_state.running_game_path, s_state.running_game_serial, s_state.running_game_title,
|
||||||
s_state.running_game_hash);
|
s_state.running_game_hash);
|
||||||
@ -4508,7 +4513,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||||||
|
|
||||||
// NOTE: Must come after the GPU thread settings update, otherwise it allocs the wrong size textures.
|
// NOTE: Must come after the GPU thread settings update, otherwise it allocs the wrong size textures.
|
||||||
const bool use_existing_textures = (g_settings.gpu_resolution_scale == old_settings.gpu_resolution_scale);
|
const bool use_existing_textures = (g_settings.gpu_resolution_scale == old_settings.gpu_resolution_scale);
|
||||||
ClearMemorySaveStates(true, use_existing_textures);
|
FreeMemoryStateStorage(false, true, use_existing_textures);
|
||||||
|
ClearMemorySaveStates(true, true);
|
||||||
|
|
||||||
if (IsPaused())
|
if (IsPaused())
|
||||||
{
|
{
|
||||||
@ -5823,6 +5829,7 @@ void System::DisplayWindowResized()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateGTEAspectRatio();
|
UpdateGTEAspectRatio();
|
||||||
|
UpdateAutomaticResolutionScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::UpdateGTEAspectRatio()
|
void System::UpdateGTEAspectRatio()
|
||||||
@ -5866,6 +5873,28 @@ void System::UpdateGTEAspectRatio()
|
|||||||
GTE::SetAspectRatio(gte_ar, custom_num, custom_denom);
|
GTE::SetAspectRatio(gte_ar, custom_num, custom_denom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void System::UpdateAutomaticResolutionScale()
|
||||||
|
{
|
||||||
|
if (!IsValidOrInitializing() || !g_settings.gpu_automatic_resolution_scale)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const u32 new_scale = g_gpu.CalculateAutomaticResolutionScale();
|
||||||
|
if (g_settings.gpu_resolution_scale == new_scale)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_settings.gpu_resolution_scale = Truncate8(new_scale);
|
||||||
|
GPUThread::UpdateSettings(true, false, false);
|
||||||
|
FreeMemoryStateStorage(false, true, false);
|
||||||
|
ClearMemorySaveStates(true, false);
|
||||||
|
|
||||||
|
if (IsPaused())
|
||||||
|
{
|
||||||
|
// resolution change needs display updated
|
||||||
|
g_gpu.UpdateDisplay(false);
|
||||||
|
GPUThread::PresentCurrentFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool System::ChangeGPUDump(std::string new_path)
|
bool System::ChangeGPUDump(std::string new_path)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
@ -50,6 +50,9 @@ void DisplayWindowResized();
|
|||||||
/// Updates the internal GTE aspect ratio. Use with "match display" aspect ratio setting.
|
/// Updates the internal GTE aspect ratio. Use with "match display" aspect ratio setting.
|
||||||
void UpdateGTEAspectRatio();
|
void UpdateGTEAspectRatio();
|
||||||
|
|
||||||
|
/// Updates the resolution scale when it is set to automatic.
|
||||||
|
void UpdateAutomaticResolutionScale();
|
||||||
|
|
||||||
/// Called on card read/write, handles fast forwarding.
|
/// Called on card read/write, handles fast forwarding.
|
||||||
void OnMemoryCardAccessed();
|
void OnMemoryCardAccessed();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user