diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 00bb5d24fc..b87ec7ded5 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -518,13 +518,26 @@ void Renderer::UpdateDrawRectangle() void Renderer::SetWindowSize(int width, int height) { - width = std::max(width, 1); - height = std::max(height, 1); - // Scale the window size by the EFB scale. if (g_ActiveConfig.iEFBScale != EFB_SCALE_AUTO_INTEGRAL) std::tie(width, height) = CalculateTargetScale(width, height); + std::tie(width, height) = CalculateOutputDimensions(width, height); + + // Track the last values of width/height to avoid sending a window resize event every frame. + if (width != m_last_window_request_width || height != m_last_window_request_height) + { + m_last_window_request_width = width; + m_last_window_request_height = height; + Host_RequestRenderWindowSize(width, height); + } +} + +std::tuple Renderer::CalculateOutputDimensions(int width, int height) +{ + width = std::max(width, 1); + height = std::max(height, 1); + float scaled_width, scaled_height; std::tie(scaled_width, scaled_height) = ScaleToDisplayAspectRatio(width, height); @@ -556,13 +569,7 @@ void Renderer::SetWindowSize(int width, int height) width -= width % 4; height -= height % 4; - // Track the last values of width/height to avoid sending a window resize event every frame. - if (width != m_last_window_request_width || height != m_last_window_request_height) - { - m_last_window_request_width = width; - m_last_window_request_height = height; - Host_RequestRenderWindowSize(width, height); - } + return std::make_tuple(width, height); } void Renderer::CheckFifoRecording() @@ -620,9 +627,11 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const // The FinishFrameData call here is necessary even after frame dumping is stopped. // If left out, screenshots are "one frame" behind, as an extra frame is dumped and buffered. FinishFrameData(); - if (IsFrameDumping()) + if (IsFrameDumping() && m_last_xfb_texture) { - auto result = m_last_xfb_texture->Map(); + UpdateFrameDumpTexture(horizontal_scale); + + auto result = m_dump_texture->Map(); if (result.has_value()) { auto raw_data = result.value(); @@ -679,6 +688,26 @@ bool Renderer::IsFrameDumping() return false; } +void Renderer::UpdateFrameDumpTexture(float horizontal_scale) +{ + int target_width, target_height; + std::tie(target_width, target_height) = CalculateOutputDimensions(m_last_xfb_texture->GetConfig().width, m_last_xfb_texture->GetConfig().height); + if (m_dump_texture == nullptr || + m_dump_texture->GetConfig().width != static_cast(target_width) || + m_dump_texture->GetConfig().height != static_cast(target_height)) + { + TextureConfig config; + config.width = target_width; + config.height = target_height; + config.rendertarget = true; + m_dump_texture = g_texture_cache->CreateTexture(config); + } + auto source_rect = m_last_xfb_texture->GetConfig().GetRect(); + source_rect.right /= horizontal_scale; + m_dump_texture->CopyRectangleFromTexture(m_last_xfb_texture, source_rect, + EFBRectangle{0, 0, target_width, target_height}); +} + void Renderer::ShutdownFrameDumping() { if (!m_frame_dump_thread_running.IsSet()) diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 11a73536e5..871939d7ab 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -181,6 +181,8 @@ protected: private: void RunFrameDumps(); void ShutdownFrameDumping(); + std::tuple CalculateOutputDimensions(int width, int height); + void UpdateFrameDumpTexture(float horizontal_scale); PEControl::PixelFormat m_prev_efb_format = PEControl::INVALID_FMT; unsigned int m_efb_scale = 1; @@ -209,6 +211,8 @@ private: AbstractTexture * m_last_xfb_texture; u64 m_last_xfb_id = 0; + std::unique_ptr m_dump_texture; + // Note: Only used for auto-ir u32 m_last_xfb_width = MAX_XFB_WIDTH; u32 m_last_xfb_height = MAX_XFB_HEIGHT; diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index bec67c042a..114127a8da 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -216,6 +216,8 @@ public: void ScaleTextureCacheEntryTo(TCacheEntry* entry, u32 new_width, u32 new_height); + virtual std::unique_ptr CreateTexture(const TextureConfig& config) = 0; + protected: TextureCacheBase(); @@ -257,8 +259,6 @@ private: std::pair FindOverlappingTextures(u32 addr, u32 size_in_bytes); - virtual std::unique_ptr CreateTexture(const TextureConfig& config) = 0; - virtual void CopyEFBToCacheEntry(TCacheEntry* entry, bool is_depth_copy, const EFBRectangle& src_rect, bool scale_by_half, unsigned int cbuf_id, const float* colmat) = 0;