From 11de923dcb7e6a7e1b29e5b15cb2bf71ede22b97 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Tue, 31 Jan 2023 17:26:46 +1300 Subject: [PATCH] Move xfb tracking and IR scaling out of RenderBase --- Source/Core/Core/State.cpp | 2 +- .../Core/VideoBackends/D3D/D3DPerfQuery.cpp | 8 +- .../VideoBackends/D3D12/D3D12PerfQuery.cpp | 4 +- .../Core/VideoBackends/Metal/MTLPerfQuery.mm | 2 +- .../Core/VideoBackends/OGL/OGLPerfQuery.cpp | 6 +- .../Core/VideoBackends/Vulkan/VKPerfQuery.cpp | 6 +- Source/Core/VideoCommon/AsyncRequests.cpp | 2 - Source/Core/VideoCommon/BPFunctions.cpp | 10 +- Source/Core/VideoCommon/BPStructs.cpp | 1 - .../Core/VideoCommon/FramebufferManager.cpp | 85 ++++++++++--- Source/Core/VideoCommon/FramebufferManager.h | 23 +++- .../Core/VideoCommon/PixelShaderManager.cpp | 6 +- Source/Core/VideoCommon/Present.cpp | 55 ++++++-- Source/Core/VideoCommon/Present.h | 16 ++- Source/Core/VideoCommon/RenderBase.cpp | 117 +----------------- Source/Core/VideoCommon/RenderBase.h | 48 +------ Source/Core/VideoCommon/TextureCacheBase.cpp | 56 ++++----- .../Core/VideoCommon/VertexShaderManager.cpp | 5 +- Source/Core/VideoCommon/VideoConfig.cpp | 23 +++- Source/Core/VideoCommon/VideoState.cpp | 11 ++ 20 files changed, 238 insertions(+), 248 deletions(-) diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 4392182a22..9f1a1c2a5a 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -96,7 +96,7 @@ static size_t s_state_writes_in_queue; static std::condition_variable s_state_write_queue_is_empty; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 157; // Last changed in PR 11183 +constexpr u32 STATE_VERSION = 158; // Last changed in PR ??? // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, diff --git a/Source/Core/VideoBackends/D3D/D3DPerfQuery.cpp b/Source/Core/VideoBackends/D3D/D3DPerfQuery.cpp index e1535f7c32..d72b88c0fb 100644 --- a/Source/Core/VideoBackends/D3D/D3DPerfQuery.cpp +++ b/Source/Core/VideoBackends/D3D/D3DPerfQuery.cpp @@ -114,8 +114,8 @@ void PerfQuery::FlushOne() // NOTE: Reported pixel metrics should be referenced to native resolution // TODO: Dropping the lower 2 bits from this count should be closer to actual // hardware behavior when drawing triangles. - const u64 native_res_result = result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / - g_renderer->GetTargetHeight(); + const u64 native_res_result = result * EFB_WIDTH / g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT / + g_framebuffer_manager->GetEFBHeight(); m_results[entry.query_group].fetch_add(static_cast(native_res_result), std::memory_order_relaxed); @@ -143,8 +143,8 @@ void PerfQuery::WeakFlush() if (hr == S_OK) { // NOTE: Reported pixel metrics should be referenced to native resolution - const u64 native_res_result = result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / - g_renderer->GetTargetHeight(); + const u64 native_res_result = result * EFB_WIDTH / g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT / + g_framebuffer_manager->GetEFBHeight(); m_results[entry.query_group].store(static_cast(native_res_result), std::memory_order_relaxed); diff --git a/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp b/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp index a6c466b646..17cb1da2d3 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp @@ -245,8 +245,8 @@ void PerfQuery::AccumulateQueriesFromBuffer(u32 query_count) // NOTE: Reported pixel metrics should be referenced to native resolution const u64 native_res_result = static_cast(result) * EFB_WIDTH / - g_renderer->GetTargetWidth() * EFB_HEIGHT / - g_renderer->GetTargetHeight(); + g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT / + g_framebuffer_manager->GetEFBHeight(); m_results[entry.query_group].fetch_add(static_cast(native_res_result), std::memory_order_relaxed); } diff --git a/Source/Core/VideoBackends/Metal/MTLPerfQuery.mm b/Source/Core/VideoBackends/Metal/MTLPerfQuery.mm index cd65b37b58..4bf37ccd22 100644 --- a/Source/Core/VideoBackends/Metal/MTLPerfQuery.mm +++ b/Source/Core/VideoBackends/Metal/MTLPerfQuery.mm @@ -78,7 +78,7 @@ void Metal::PerfQuery::ReturnResults(const u64* data, const PerfQueryGroup* grou for (size_t i = 0; i < count; ++i) { u64 native_res_result = data[i] * (EFB_WIDTH * EFB_HEIGHT) / - (g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight()); + (g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight()); native_res_result /= g_ActiveConfig.iMultisamples; diff --git a/Source/Core/VideoBackends/OGL/OGLPerfQuery.cpp b/Source/Core/VideoBackends/OGL/OGLPerfQuery.cpp index cae5f71297..a5bd155afb 100644 --- a/Source/Core/VideoBackends/OGL/OGLPerfQuery.cpp +++ b/Source/Core/VideoBackends/OGL/OGLPerfQuery.cpp @@ -9,7 +9,7 @@ #include "Common/GL/GLExtensions/GLExtensions.h" #include "VideoBackends/OGL/OGLGfx.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" @@ -165,7 +165,7 @@ void PerfQueryGL::FlushOne() // TODO: Dropping the lower 2 bits from this count should be closer to actual // hardware behavior when drawing triangles. result = static_cast(result) * EFB_WIDTH * EFB_HEIGHT / - (g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight()); + (g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight()); // Adjust for multisampling if (g_ActiveConfig.iMultisamples > 1) @@ -265,7 +265,7 @@ void PerfQueryGLESNV::FlushOne() // TODO: Dropping the lower 2 bits from this count should be closer to actual // hardware behavior when drawing triangles. const u64 native_res_result = static_cast(result) * EFB_WIDTH * EFB_HEIGHT / - (g_renderer->GetTargetWidth() * g_renderer->GetTargetHeight()); + (g_framebuffer_manager->GetEFBWidth() * g_framebuffer_manager->GetEFBHeight()); m_results[entry.query_group].fetch_add(static_cast(native_res_result), std::memory_order_relaxed); diff --git a/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp b/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp index d362deaf37..d16c8c379b 100644 --- a/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKPerfQuery.cpp @@ -15,7 +15,7 @@ #include "VideoBackends/Vulkan/StateTracker.h" #include "VideoBackends/Vulkan/VKGfx.h" #include "VideoBackends/Vulkan/VulkanContext.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/VideoCommon.h" namespace Vulkan @@ -219,8 +219,8 @@ void PerfQuery::ReadbackQueries(u32 query_count) // NOTE: Reported pixel metrics should be referenced to native resolution const u64 native_res_result = static_cast(m_query_result_buffer[i]) * EFB_WIDTH / - g_renderer->GetTargetWidth() * EFB_HEIGHT / - g_renderer->GetTargetHeight(); + g_framebuffer_manager->GetEFBWidth() * EFB_HEIGHT / + g_framebuffer_manager->GetEFBHeight(); m_results[entry.query_group].fetch_add(static_cast(native_res_result), std::memory_order_relaxed); } diff --git a/Source/Core/VideoCommon/AsyncRequests.cpp b/Source/Core/VideoCommon/AsyncRequests.cpp index 7cbb134f7e..8c254d4e71 100644 --- a/Source/Core/VideoCommon/AsyncRequests.cpp +++ b/Source/Core/VideoCommon/AsyncRequests.cpp @@ -158,8 +158,6 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e) case Event::SWAP_EVENT: g_presenter->ViSwap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride, e.swap_event.fbHeight, e.time); - g_renderer->TrackSwaps(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride, - e.swap_event.fbHeight, e.time); break; case Event::BBOX_READ: diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index d022f46103..ef705a50fd 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -198,7 +198,7 @@ void SetScissorAndViewport() { auto native_rc = ComputeScissorRects().Best(); - auto target_rc = g_renderer->ConvertEFBRectangle(native_rc.rect); + auto target_rc = g_framebuffer_manager->ConvertEFBRectangle(native_rc.rect); auto converted_rc = g_gfx->ConvertFramebufferRectangle(target_rc, g_gfx->GetCurrentFramebuffer()); g_gfx->SetScissorRect(converted_rc); @@ -216,10 +216,10 @@ void SetScissorAndViewport() raw_height = std::round(raw_height); } - float x = g_renderer->EFBToScaledXf(raw_x); - float y = g_renderer->EFBToScaledYf(raw_y); - float width = g_renderer->EFBToScaledXf(raw_width); - float height = g_renderer->EFBToScaledYf(raw_height); + float x = g_framebuffer_manager->EFBToScaledXf(raw_x); + float y = g_framebuffer_manager->EFBToScaledYf(raw_y); + float width = g_framebuffer_manager->EFBToScaledXf(raw_width); + float height = g_framebuffer_manager->EFBToScaledYf(raw_height); float min_depth = (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f; float max_depth = xfmem.viewport.farZ / 16777216.0f; if (width < 0.f) diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 1985ac6527..6d50377950 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -352,7 +352,6 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, // below div two to convert from bytes to pixels - it expects width, not stride u64 ticks = Core::System::GetInstance().GetCoreTiming().GetTicks(); g_presenter->ImmediateSwap(destAddr, destStride / 2, destStride, height, ticks); - g_renderer->TrackSwaps(destAddr, destStride / 2, destStride, height, ticks); } else { diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index 5696ebb2b8..38cab15f00 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -10,6 +10,7 @@ #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Core/Config/GraphicsSettings.h" +#include "Core/System.h" #include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractPipeline.h" @@ -19,7 +20,8 @@ #include "VideoCommon/BPFunctions.h" #include "VideoCommon/DriverDetails.h" #include "VideoCommon/FramebufferShaderGen.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/Present.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" @@ -145,16 +147,16 @@ static u32 CalculateEFBLayers() return (g_ActiveConfig.stereo_mode != StereoMode::Off) ? 2 : 1; } -TextureConfig FramebufferManager::GetEFBColorTextureConfig() +TextureConfig FramebufferManager::GetEFBColorTextureConfig(u32 width, u32 height) { - return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1, + return TextureConfig(width, height, 1, CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBColorFormat(), AbstractTextureFlag_RenderTarget); } -TextureConfig FramebufferManager::GetEFBDepthTextureConfig() +TextureConfig FramebufferManager::GetEFBDepthTextureConfig(u32 width, u32 height) { - return TextureConfig(g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), 1, + return TextureConfig(width, height, 1, CalculateEFBLayers(), g_ActiveConfig.iMultisamples, GetEFBDepthFormat(), AbstractTextureFlag_RenderTarget); } @@ -169,10 +171,65 @@ FramebufferState FramebufferManager::GetEFBFramebufferState() const return ret; } +MathUtil::Rectangle +FramebufferManager::ConvertEFBRectangle(const MathUtil::Rectangle& rc) const +{ + MathUtil::Rectangle result; + result.left = EFBToScaledX(rc.left); + result.top = EFBToScaledY(rc.top); + result.right = EFBToScaledX(rc.right); + result.bottom = EFBToScaledY(rc.bottom); + return result; +} + +unsigned int FramebufferManager::GetEFBScale() const +{ + return m_efb_scale; +} + +int FramebufferManager::EFBToScaledX(int x) const +{ + return x * static_cast(m_efb_scale); +} + +int FramebufferManager::EFBToScaledY(int y) const +{ + return y * static_cast(m_efb_scale); +} + +float FramebufferManager::EFBToScaledXf(float x) const +{ + return x * ((float)GetEFBWidth() / (float)EFB_WIDTH); +} + +float FramebufferManager::EFBToScaledYf(float y) const +{ + return y * ((float)GetEFBHeight() / (float)EFB_HEIGHT); +} + +std::tuple FramebufferManager::CalculateTargetSize() +{ + if (g_ActiveConfig.iEFBScale == EFB_SCALE_AUTO_INTEGRAL) + m_efb_scale = g_presenter->AutoIntegralScale(); + else + m_efb_scale = g_ActiveConfig.iEFBScale; + + const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize; + if (max_size < EFB_WIDTH * m_efb_scale) + m_efb_scale = max_size / EFB_WIDTH; + + u32 new_efb_width = std::max(EFB_WIDTH * static_cast(m_efb_scale), 1u); + u32 new_efb_height = std::max(EFB_HEIGHT * static_cast(m_efb_scale), 1u); + + return std::make_tuple(new_efb_width, new_efb_height); +} + bool FramebufferManager::CreateEFBFramebuffer() { - const TextureConfig efb_color_texture_config = GetEFBColorTextureConfig(); - const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig(); + auto [width, height] = CalculateTargetSize(); + + const TextureConfig efb_color_texture_config = GetEFBColorTextureConfig(width, height); + const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig(width, height); // We need a second texture to swap with for changing pixel formats m_efb_color_texture = g_gfx->CreateTexture(efb_color_texture_config, "EFB color texture"); @@ -634,7 +691,7 @@ void FramebufferManager::DestroyReadbackPipelines() bool FramebufferManager::CreateReadbackFramebuffer() { - if (g_renderer->GetEFBScale() != 1) + if (GetEFBScale() != 1) { const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, @@ -655,7 +712,7 @@ bool FramebufferManager::CreateReadbackFramebuffer() (IsUsingTiledEFBCache() && !g_ActiveConfig.backend_info.bSupportsPartialDepthCopies) || !AbstractTexture::IsCompatibleDepthAndColorFormats(m_efb_depth_texture->GetFormat(), GetEFBDepthCopyFormat()) || - g_renderer->GetEFBScale() != 1) + GetEFBScale() != 1) { const TextureConfig depth_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, @@ -732,10 +789,10 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async // Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on. EFBCacheData& data = depth ? m_efb_depth_cache : m_efb_color_cache; const MathUtil::Rectangle rect = GetEFBCacheTileRect(tile_index); - const MathUtil::Rectangle native_rect = g_renderer->ConvertEFBRectangle(rect); + const MathUtil::Rectangle native_rect = ConvertEFBRectangle(rect); AbstractTexture* src_texture = depth ? ResolveEFBDepthTexture(native_rect) : ResolveEFBColorTexture(native_rect); - if (g_renderer->GetEFBScale() != 1 || force_intermediate_copy) + if (GetEFBScale() != 1 || force_intermediate_copy) { // Downsample from internal resolution to 1x. // TODO: This won't produce correct results at IRs above 2x. More samples are required. @@ -795,9 +852,9 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool color FlagPeekCacheAsOutOfDate(); // Native -> EFB coordinates - MathUtil::Rectangle target_rc = g_renderer->ConvertEFBRectangle(rc); + MathUtil::Rectangle target_rc = ConvertEFBRectangle(rc); target_rc = g_gfx->ConvertFramebufferRectangle(target_rc, m_efb_framebuffer.get()); - target_rc.ClampUL(0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); + target_rc.ClampUL(0, 0, m_efb_framebuffer->GetWidth(), m_efb_framebuffer->GetWidth()); // Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha // channel to 0xFF. @@ -925,7 +982,7 @@ void FramebufferManager::CreatePokeVertices(std::vector* destinat // GPU will expand the point to a quad. const float cs_x = (static_cast(x) + 0.5f) * cs_pixel_width - 1.0f; const float cs_y = 1.0f - (static_cast(y) + 0.5f) * cs_pixel_height; - const float point_size = static_cast(g_renderer->GetEFBScale()); + const float point_size = static_cast(GetEFBScale()); destination_list->push_back({{cs_x, cs_y, z, point_size}, color}); return; } diff --git a/Source/Core/VideoCommon/FramebufferManager.h b/Source/Core/VideoCommon/FramebufferManager.h index c3871c8e15..0eb5d4aa93 100644 --- a/Source/Core/VideoCommon/FramebufferManager.h +++ b/Source/Core/VideoCommon/FramebufferManager.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "Common/CommonTypes.h" #include "Common/EnumFormatter.h" @@ -54,8 +55,8 @@ public: static AbstractTextureFormat GetEFBColorFormat(); static AbstractTextureFormat GetEFBDepthFormat(); static AbstractTextureFormat GetEFBDepthCopyFormat(); - static TextureConfig GetEFBColorTextureConfig(); - static TextureConfig GetEFBDepthTextureConfig(); + static TextureConfig GetEFBColorTextureConfig(u32 width, u32 height); + static TextureConfig GetEFBDepthTextureConfig(u32 width, u32 height); // Accessors. AbstractTexture* GetEFBColorTexture() const { return m_efb_color_texture.get(); } @@ -69,6 +70,20 @@ public: bool IsEFBStereo() const { return m_efb_color_texture->GetLayers() > 1; } FramebufferState GetEFBFramebufferState() const; + // EFB coordinate conversion functions + // Use this to convert a whole native EFB rect to backbuffer coordinates + MathUtil::Rectangle ConvertEFBRectangle(const MathUtil::Rectangle& rc) const; + + unsigned int GetEFBScale() const; + + // Use this to upscale native EFB coordinates to IDEAL internal resolution + int EFBToScaledX(int x) const; + int EFBToScaledY(int y) const; + + // Floating point versions of the above - only use them if really necessary + float EFBToScaledXf(float x) const; + float EFBToScaledYf(float y) const; + // First-time setup. bool Initialize(); @@ -172,9 +187,13 @@ protected: void DrawPokeVertices(const EFBPokeVertex* vertices, u32 vertex_count, const AbstractPipeline* pipeline); + std::tuple CalculateTargetSize(); + void DoLoadState(PointerWrap& p); void DoSaveState(PointerWrap& p); + float m_efb_scale = 0.0f; + std::unique_ptr m_efb_color_texture; std::unique_ptr m_efb_convert_color_texture; std::unique_ptr m_efb_depth_texture; diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index 35db2c6684..c929db6995 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -7,7 +7,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoConfig.h" #include "VideoCommon/XFMemory.h" @@ -74,7 +74,7 @@ void PixelShaderManager::Dirty() // Any constants that can changed based on settings should be re-calculated m_fog_range_adjusted_changed = true; - SetEfbScaleChanged(g_renderer->EFBToScaledXf(1), g_renderer->EFBToScaledYf(1)); + SetEfbScaleChanged(g_framebuffer_manager->EFBToScaledXf(1), g_framebuffer_manager->EFBToScaledYf(1)); SetFogParamChanged(); dirty = true; @@ -103,7 +103,7 @@ void PixelShaderManager::SetConstants() // TODO: Shouldn't this be EFBToScaledXf? constants.fogf[2] = ScreenSpaceCenter; constants.fogf[3] = - static_cast(g_renderer->EFBToScaledX(static_cast(2.0f * xfmem.viewport.wd))); + static_cast(g_framebuffer_manager->EFBToScaledX(static_cast(2.0f * xfmem.viewport.wd))); for (size_t i = 0, vec_index = 0; i < std::size(bpmem.fogRange.K); i++) { diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index 0612d96d3b..b7a60c7dc6 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -3,6 +3,7 @@ #include "VideoCommon/Present.h" +#include "Common/ChunkFile.h" #include "Core/HW/VideoInterface.h" #include "Core/Host.h" @@ -17,6 +18,7 @@ #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoEvents.h" +#include "Present.h" std::unique_ptr g_presenter; @@ -61,35 +63,39 @@ bool Presenter::Initialize() return true; } -bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height) +bool Presenter::FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) { ReleaseXFBContentLock(); m_xfb_entry = g_texture_cache->GetXFBTexture(xfb_addr, fb_width, fb_height, fb_stride, &m_xfb_rect); + bool is_duplicate = m_xfb_entry->id == m_last_xfb_id; m_xfb_entry->AcquireContentLock(); - if (m_last_xfb_id == m_xfb_entry->id) - return false; + m_last_xfb_addr = xfb_addr; + m_last_xfb_ticks = ticks; + m_last_xfb_width = fb_width; + m_last_xfb_stride = fb_stride; + m_last_xfb_height = fb_height; m_last_xfb_id = m_xfb_entry->id; - return true; + return is_duplicate; } void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) { - bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height); + bool unique = FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks); PresentInfo present_info; present_info.emulated_timestamp = ticks; if (unique) { - present_info.frame_count = g_renderer->FrameCountIncrement(); + present_info.frame_count = m_frame_count++; present_info.reason = PresentInfo::PresentReason::VideoInterface; } else { - present_info.frame_count = g_renderer->FrameCount() - 1; // Previous frame + present_info.frame_count = m_frame_count - 1; // Previous frame present_info.reason = PresentInfo::PresentReason::VideoInterfaceDuplicate; } present_info.present_count = m_present_count; @@ -111,11 +117,11 @@ void Presenter::ViSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, void Presenter::ImmediateSwap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) { - FetchXFB(xfb_addr, fb_width, fb_stride, fb_height); + FetchXFB(xfb_addr, fb_width, fb_stride, fb_height, ticks); PresentInfo present_info; present_info.emulated_timestamp = ticks; - present_info.frame_count = g_renderer->FrameCountIncrement(); + present_info.frame_count = m_frame_count++; present_info.reason = PresentInfo::PresentReason::Immediate; present_info.present_count = m_present_count++; @@ -145,7 +151,7 @@ void Presenter::ProcessFrameDumping(u64 ticks) const } g_frame_dumper->DumpCurrentFrame(m_xfb_entry->texture.get(), m_xfb_rect, target_rect, ticks, - g_renderer->FrameCount()); + m_frame_count); } } @@ -307,6 +313,13 @@ void* Presenter::GetNewSurfaceHandle() return handle; } +u32 Presenter::AutoIntegralScale() const +{ + // Calculate a scale based on the window size + u32 width = EFB_WIDTH * m_target_rectangle.GetWidth() / m_last_xfb_width; + u32 height = EFB_HEIGHT * m_target_rectangle.GetHeight() / m_last_xfb_height; + return std::max((width - 1) / EFB_WIDTH + 1, (height - 1) / EFB_HEIGHT + 1); +} void Presenter::SetWindowSize(int width, int height) { const auto [out_width, out_height] = g_presenter->CalculateOutputDimensions(width, height); @@ -577,4 +590,26 @@ void Presenter::SetMousePress(u32 button_mask) m_onscreen_ui->SetMousePress(button_mask); } +void Presenter::DoState(PointerWrap& p) +{ + p.Do(m_frame_count); + p.Do(m_last_xfb_ticks); + p.Do(m_last_xfb_addr); + p.Do(m_last_xfb_width); + p.Do(m_last_xfb_stride); + p.Do(m_last_xfb_height); + + if (p.IsReadMode()) + { + // This technically counts as the end of the frame + AfterFrameEvent::Trigger(); + + // re-display the most recent XFB + ImmediateSwap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride, + m_last_xfb_height, m_last_xfb_ticks); + } + +} + + } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Present.h b/Source/Core/VideoCommon/Present.h index fb4799898c..235dba11d4 100644 --- a/Source/Core/VideoCommon/Present.h +++ b/Source/Core/VideoCommon/Present.h @@ -8,6 +8,7 @@ #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureConfig.h" +#include "VideoCommon/VideoCommon.h" #include #include @@ -47,6 +48,7 @@ public: int GetBackbufferWidth() const { return m_backbuffer_width; } int GetBackbufferHeight() const { return m_backbuffer_height; } float GetBackbufferScale() const { return m_backbuffer_scale; } + u32 AutoIntegralScale() const; AbstractTextureFormat GetBackbufferFormat() const { return m_backbuffer_format; } void SetWindowSize(int width, int height); void SetBackbuffer(int backbuffer_width, int backbuffer_height); @@ -86,12 +88,16 @@ public: void SetMousePos(float x, float y); void SetMousePress(u32 button_mask); + int FrameCount() const { return m_frame_count; } + + void DoState(PointerWrap& p); + const MathUtil::Rectangle& GetTargetRectangle() const { return m_target_rectangle; } private: // Fetches the XFB texture from the texture cache. // Returns true the contents have changed since last time - bool FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height); + bool FetchXFB(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks); void ProcessFrameDumping(u64 ticks) const; @@ -130,7 +136,15 @@ private: std::unique_ptr m_post_processor; std::unique_ptr m_onscreen_ui; + u64 m_frame_count = 0; u64 m_present_count = 0; + + // XFB tracking + u64 m_last_xfb_ticks = 0; + u32 m_last_xfb_addr = 0; + u32 m_last_xfb_width = MAX_XFB_WIDTH; + u32 m_last_xfb_stride = 0; + u32 m_last_xfb_height = MAX_XFB_HEIGHT; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 6c991c74ae..c30495f9d1 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -37,7 +37,6 @@ #include "VideoCommon/FrameDumper.h" #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/PixelEngine.h" -#include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/Present.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoBackendBase.h" @@ -48,10 +47,8 @@ std::unique_ptr g_renderer; Renderer::Renderer() - : m_prev_efb_format{PixelFormat::INVALID_FMT}, - m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT} + : m_prev_efb_format{PixelFormat::INVALID_FMT} { - CalculateTargetSize(); UpdateWidescreen(); m_config_changed_handle = ConfigChangedEvent::Register([this](u32 bits) { OnConfigChanged(bits); }, "Renderer"); @@ -168,83 +165,6 @@ void Renderer::PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num } } -unsigned int Renderer::GetEFBScale() const -{ - return m_efb_scale; -} - -int Renderer::EFBToScaledX(int x) const -{ - return x * static_cast(m_efb_scale); -} - -int Renderer::EFBToScaledY(int y) const -{ - return y * static_cast(m_efb_scale); -} - -float Renderer::EFBToScaledXf(float x) const -{ - return x * ((float)GetTargetWidth() / (float)EFB_WIDTH); -} - -float Renderer::EFBToScaledYf(float y) const -{ - return y * ((float)GetTargetHeight() / (float)EFB_HEIGHT); -} - -std::tuple Renderer::CalculateTargetScale(int x, int y) const -{ - return std::make_tuple(x * static_cast(m_efb_scale), y * static_cast(m_efb_scale)); -} - -// return true if target size changed -bool Renderer::CalculateTargetSize() -{ - if (g_ActiveConfig.iEFBScale == EFB_SCALE_AUTO_INTEGRAL) - { - auto target_rectangle = g_presenter->GetTargetRectangle(); - // Set a scale based on the window size - int width = EFB_WIDTH * target_rectangle.GetWidth() / m_last_xfb_width; - int height = EFB_HEIGHT * target_rectangle.GetHeight() / m_last_xfb_height; - m_efb_scale = std::max((width - 1) / EFB_WIDTH + 1, (height - 1) / EFB_HEIGHT + 1); - } - else - { - m_efb_scale = g_ActiveConfig.iEFBScale; - } - - const u32 max_size = g_ActiveConfig.backend_info.MaxTextureSize; - if (max_size < EFB_WIDTH * m_efb_scale) - m_efb_scale = max_size / EFB_WIDTH; - - auto [new_efb_width, new_efb_height] = CalculateTargetScale(EFB_WIDTH, EFB_HEIGHT); - new_efb_width = std::max(new_efb_width, 1); - new_efb_height = std::max(new_efb_height, 1); - - if (new_efb_width != m_target_width || new_efb_height != m_target_height) - { - m_target_width = new_efb_width; - m_target_height = new_efb_height; - auto& system = Core::System::GetInstance(); - auto& pixel_shader_manager = system.GetPixelShaderManager(); - pixel_shader_manager.SetEfbScaleChanged(EFBToScaledXf(1), EFBToScaledYf(1)); - return true; - } - return false; -} - - -MathUtil::Rectangle Renderer::ConvertEFBRectangle(const MathUtil::Rectangle& rc) const -{ - MathUtil::Rectangle result; - result.left = EFBToScaledX(rc.left); - result.top = EFBToScaledY(rc.top); - result.right = EFBToScaledX(rc.right); - result.bottom = EFBToScaledY(rc.bottom); - return result; -} - void Renderer::UpdateWidescreen() { if (SConfig::GetInstance().bWii) @@ -324,20 +244,7 @@ void Renderer::OnConfigChanged(u32 bits) UpdateWidescreen(); } -void Renderer::TrackSwaps(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks) -{ - if (xfb_addr && fb_width && fb_stride && fb_height) - { - // Update our last xfb values - m_last_xfb_addr = xfb_addr; - m_last_xfb_ticks = ticks; - m_last_xfb_width = fb_width; - m_last_xfb_stride = fb_stride; - m_last_xfb_height = fb_height; - } -} - -bool Renderer::UseVertexDepthRange() const +bool Renderer::UseVertexDepthRange() { // We can't compute the depth range in the vertex shader if we don't support depth clamp. if (!g_ActiveConfig.backend_info.bSupportsDepthClamp) @@ -359,29 +266,9 @@ bool Renderer::UseVertexDepthRange() const void Renderer::DoState(PointerWrap& p) { p.Do(m_is_game_widescreen); - p.Do(m_frame_count); - p.Do(m_prev_efb_format); - p.Do(m_last_xfb_ticks); - p.Do(m_last_xfb_addr); - p.Do(m_last_xfb_width); - p.Do(m_last_xfb_stride); - p.Do(m_last_xfb_height); - - g_bounding_box->DoState(p); if (p.IsReadMode()) { m_was_orthographically_anamorphic = false; - - // This technically counts as the end of the frame - AfterFrameEvent::Trigger(); - - // re-display the most recent XFB - g_presenter->ImmediateSwap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride, - m_last_xfb_height, m_last_xfb_ticks); } - -#if defined(HAVE_FFMPEG) - g_frame_dumper->DoState(p); -#endif } diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index c1c00aa382..52415c0f36 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -25,80 +25,38 @@ struct EfbPokeData // Renderer really isn't a very good name for this class - it's more like "Misc". // It used to be a massive mess, but almost everything has been refactored out. // -// Most of the remaining functionality is related to EFB and Internal Resolution scaling -// -// It also handles the Widescreen heuristic, frame counting and tracking xfb across save states. +// All that's left is Widescreen tracking, pixel format and a thin abstraction layer +// for VideoSoftware to intercept EFB accesses. class Renderer { public: Renderer(); virtual ~Renderer(); - // Ideal internal resolution - multiple of the native EFB resolution - int GetTargetWidth() const { return m_target_width; } - int GetTargetHeight() const { return m_target_height; } - - // EFB coordinate conversion functions - // Use this to convert a whole native EFB rect to backbuffer coordinates - MathUtil::Rectangle ConvertEFBRectangle(const MathUtil::Rectangle& rc) const; - - unsigned int GetEFBScale() const; - - // Use this to upscale native EFB coordinates to IDEAL internal resolution - int EFBToScaledX(int x) const; - int EFBToScaledY(int y) const; - - // Floating point versions of the above - only use them if really necessary - float EFBToScaledXf(float x) const; - float EFBToScaledYf(float y) const; - virtual void ReinterpretPixelData(EFBReinterpretType convtype); virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); virtual void PokeEFB(EFBAccessType type, const EfbPokeData* points, size_t num_points); - // Track swaps for save-states - void TrackSwaps(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks); - bool IsGameWidescreen() const { return m_is_game_widescreen; } PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; } void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; } - bool UseVertexDepthRange() const; + static bool UseVertexDepthRange(); void DoState(PointerWrap& p); - bool CalculateTargetSize(); - - int FrameCount() const { return m_frame_count; } - int FrameCountIncrement() { return m_frame_count++; } - void OnConfigChanged(u32 bits); protected: void UpdateWidescreen(); void UpdateWidescreenHeuristic(); - std::tuple CalculateTargetScale(int x, int y) const; - bool m_is_game_widescreen = false; bool m_was_orthographically_anamorphic = false; - // The framebuffer size - int m_target_width = 1; - int m_target_height = 1; - private: PixelFormat m_prev_efb_format; - unsigned int m_efb_scale = 1; - - u64 m_last_xfb_ticks = 0; - u32 m_last_xfb_addr = 0; - u32 m_last_xfb_width = 0; - u32 m_last_xfb_stride = 0; - u32 m_last_xfb_height = 0; - - int m_frame_count = 0; EventHook m_update_widescreen_handle; EventHook m_config_changed_handle; diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 947b2e5965..02601baaf4 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -44,7 +44,7 @@ #include "VideoCommon/HiresTextures.h" #include "VideoCommon/OpcodeDecoding.h" #include "VideoCommon/PixelShaderManager.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/Present.h" #include "VideoCommon/ShaderCache.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/TMEM.h" @@ -783,7 +783,7 @@ void TextureCacheBase::OnFrameEnd() g_texture_cache->FlushEFBCopies(); } - g_texture_cache->Cleanup(g_renderer->FrameCount()); + g_texture_cache->Cleanup(g_presenter->FrameCount()); } void TCacheEntry::DoState(PointerWrap& p) @@ -921,17 +921,17 @@ RcTcacheEntry TextureCacheBase::DoPartialTextureUpdates(RcTcacheEntry& entry_to_ entry->native_width != entry->GetWidth() || entry->native_height != entry->GetHeight()) { ScaleTextureCacheEntryTo(entry_to_update, - g_renderer->EFBToScaledX(entry_to_update->native_width), - g_renderer->EFBToScaledY(entry_to_update->native_height)); - ScaleTextureCacheEntryTo(entry, g_renderer->EFBToScaledX(entry->native_width), - g_renderer->EFBToScaledY(entry->native_height)); + g_framebuffer_manager->EFBToScaledX(entry_to_update->native_width), + g_framebuffer_manager->EFBToScaledY(entry_to_update->native_height)); + ScaleTextureCacheEntryTo(entry, g_framebuffer_manager->EFBToScaledX(entry->native_width), + g_framebuffer_manager->EFBToScaledY(entry->native_height)); - src_x = g_renderer->EFBToScaledX(src_x); - src_y = g_renderer->EFBToScaledY(src_y); - dst_x = g_renderer->EFBToScaledX(dst_x); - dst_y = g_renderer->EFBToScaledY(dst_y); - copy_width = g_renderer->EFBToScaledX(copy_width); - copy_height = g_renderer->EFBToScaledY(copy_height); + src_x = g_framebuffer_manager->EFBToScaledX(src_x); + src_y = g_framebuffer_manager->EFBToScaledY(src_y); + dst_x = g_framebuffer_manager->EFBToScaledX(dst_x); + dst_y = g_framebuffer_manager->EFBToScaledY(dst_y); + copy_width = g_framebuffer_manager->EFBToScaledX(copy_width); + copy_height = g_framebuffer_manager->EFBToScaledY(copy_height); } // If the source rectangle is outside of what we actually have in VRAM, skip the copy. @@ -1091,7 +1091,7 @@ static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex, // that have arbitrary contents, eg. are used for fog effects where the // distance they kick in at is important to preserve at any resolution. // Correct this with the upscaling factor of custom textures. - s32 lod_offset = std::log2(g_renderer->GetEFBScale() / custom_tex_scale) * 256.f; + s32 lod_offset = std::log2(g_framebuffer_manager->GetEFBScale() / custom_tex_scale) * 256.f; state.tm0.lod_bias = std::clamp(state.tm0.lod_bias + lod_offset, -32768, 32767); // Anisotropic also pushes mips farther away so it cannot be used either @@ -1957,8 +1957,8 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry) // copies to be stitched together. if (create_upscaled_copy) { - ScaleTextureCacheEntryTo(stitched_entry, g_renderer->EFBToScaledX(stitched_entry->native_width), - g_renderer->EFBToScaledY(stitched_entry->native_height)); + ScaleTextureCacheEntryTo(stitched_entry, g_framebuffer_manager->EFBToScaledX(stitched_entry->native_width), + g_framebuffer_manager->EFBToScaledY(stitched_entry->native_height)); } for (TCacheEntry* entry : candidates) @@ -1993,17 +1993,17 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry) // Scale to internal resolution. if (entry->native_width != entry->GetWidth()) { - src_x = g_renderer->EFBToScaledX(src_x); - src_y = g_renderer->EFBToScaledY(src_y); - src_width = g_renderer->EFBToScaledX(src_width); - src_height = g_renderer->EFBToScaledY(src_height); + src_x = g_framebuffer_manager->EFBToScaledX(src_x); + src_y = g_framebuffer_manager->EFBToScaledY(src_y); + src_width = g_framebuffer_manager->EFBToScaledX(src_width); + src_height = g_framebuffer_manager->EFBToScaledY(src_height); } if (create_upscaled_copy) { - dst_x = g_renderer->EFBToScaledX(dst_x); - dst_y = g_renderer->EFBToScaledY(dst_y); - dst_width = g_renderer->EFBToScaledX(dst_width); - dst_height = g_renderer->EFBToScaledY(dst_height); + dst_x = g_framebuffer_manager->EFBToScaledX(dst_x); + dst_y = g_framebuffer_manager->EFBToScaledY(dst_y); + dst_width = g_framebuffer_manager->EFBToScaledX(dst_width); + dst_height = g_framebuffer_manager->EFBToScaledY(dst_height); } // If the source rectangle is outside of what we actually have in VRAM, skip the copy. @@ -2183,8 +2183,8 @@ void TextureCacheBase::CopyRenderTargetToTexture( // For the latter, we keep the EFB resolution for the virtual XFB blit. u32 tex_w = width; u32 tex_h = height; - u32 scaled_tex_w = g_renderer->EFBToScaledX(width); - u32 scaled_tex_h = g_renderer->EFBToScaledY(height); + u32 scaled_tex_w = g_framebuffer_manager->EFBToScaledX(width); + u32 scaled_tex_h = g_framebuffer_manager->EFBToScaledY(height); if (scaleByHalf) { @@ -2269,7 +2269,7 @@ void TextureCacheBase::CopyRenderTargetToTexture( // TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more // complex down filtering to average all pixels and produce the correct result. const bool linear_filter = - !is_depth_copy && (scaleByHalf || g_renderer->GetEFBScale() != 1 || y_scale > 1.0f); + !is_depth_copy && (scaleByHalf || g_framebuffer_manager->GetEFBScale() != 1 || y_scale > 1.0f); RcTcacheEntry entry; if (copy_to_vram) @@ -2803,7 +2803,7 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c return; } - const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect); + const auto scaled_src_rect = g_framebuffer_manager->ConvertEFBRectangle(src_rect); const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle( scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer()); AbstractTexture* src_texture = @@ -2877,7 +2877,7 @@ void TextureCacheBase::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams& return; } - const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect); + const auto scaled_src_rect = g_framebuffer_manager->ConvertEFBRectangle(src_rect); const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle( scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer()); AbstractTexture* src_texture = diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 3779051b6b..f2a203cfe1 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -20,6 +20,7 @@ #include "VideoCommon/BPFunctions.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/CPMemory.h" +#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FreeLookCamera.h" #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h" #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h" @@ -339,10 +340,10 @@ void VertexShaderManager::SetConstants(const std::vector& textures) const bool bUseVertexRounding = g_ActiveConfig.UseVertexRounding(); const float viewport_width = bUseVertexRounding ? (2.f * xfmem.viewport.wd) : - g_renderer->EFBToScaledXf(2.f * xfmem.viewport.wd); + g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.wd); const float viewport_height = bUseVertexRounding ? (2.f * xfmem.viewport.ht) : - g_renderer->EFBToScaledXf(2.f * xfmem.viewport.ht); + g_framebuffer_manager->EFBToScaledXf(2.f * xfmem.viewport.ht); const float pixel_size_x = 2.f / viewport_width; const float pixel_size_y = 2.f / viewport_height; constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x; diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 7f710730bc..21f006af4a 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -14,6 +14,7 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/Movie.h" +#include "Core/System.h" #include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPFunctions.h" @@ -24,7 +25,7 @@ #include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/Present.h" -#include "VideoCommon/RenderBase.h" +#include "VideoCommon/PixelShaderManager.h" #include "VideoCommon/ShaderGenCommon.h" #include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/VertexManagerBase.h" @@ -253,6 +254,7 @@ void CheckForConfigChanges() const auto old_texture_filtering_mode = g_ActiveConfig.texture_filtering_mode; const bool old_vsync = g_ActiveConfig.bVSyncActive; const bool old_bbox = g_ActiveConfig.bBBoxEnable; + const int old_efb_scale = g_ActiveConfig.iEFBScale; const u32 old_game_mod_changes = g_ActiveConfig.graphics_mod_config ? g_ActiveConfig.graphics_mod_config->GetChangeCount() : 0; const bool old_graphics_mods_enabled = g_ActiveConfig.bGraphicMods; @@ -302,7 +304,7 @@ void CheckForConfigChanges() changed_bits |= CONFIG_CHANGE_BIT_VSYNC; if (old_bbox != g_ActiveConfig.bBBoxEnable) changed_bits |= CONFIG_CHANGE_BIT_BBOX; - if (g_renderer->CalculateTargetSize()) + if (old_efb_scale != g_ActiveConfig.iEFBScale) changed_bits |= CONFIG_CHANGE_BIT_TARGET_SIZE; if (old_suggested_aspect_mode != g_ActiveConfig.suggested_aspect_mode) changed_bits |= CONFIG_CHANGE_BIT_ASPECT_RATIO; @@ -315,10 +317,7 @@ void CheckForConfigChanges() if (changed_bits == 0) return; - // Notify all listeners - ConfigChangedEvent::Trigger(changed_bits); - - // TODO: Move everything else to the ConfigChanged event + float old_scale = g_framebuffer_manager->GetEFBScale(); // Framebuffer changed? if (changed_bits & (CONFIG_CHANGE_BIT_MULTISAMPLES | CONFIG_CHANGE_BIT_STEREO_MODE | @@ -327,6 +326,13 @@ void CheckForConfigChanges() g_framebuffer_manager->RecreateEFBFramebuffer(); } + if (old_scale != g_framebuffer_manager->GetEFBScale()) + { + auto& system = Core::System::GetInstance(); + auto& pixel_shader_manager = system.GetPixelShaderManager(); + pixel_shader_manager.Dirty(); + } + // Reload shaders if host config has changed. if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES)) { @@ -342,6 +348,11 @@ void CheckForConfigChanges() { BPFunctions::SetScissorAndViewport(); } + + // Notify all listeners + ConfigChangedEvent::Trigger(changed_bits); + + // TODO: Move everything else to the ConfigChanged event } static EventHook s_check_config_event = AfterFrameEvent::Register([] { diff --git a/Source/Core/VideoCommon/VideoState.cpp b/Source/Core/VideoCommon/VideoState.cpp index 75e9e4d3bc..6981e14adb 100644 --- a/Source/Core/VideoCommon/VideoState.cpp +++ b/Source/Core/VideoCommon/VideoState.cpp @@ -7,15 +7,18 @@ #include "Common/ChunkFile.h" #include "Core/System.h" +#include "VideoCommon/BoundingBox.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/BPStructs.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/CommandProcessor.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/FramebufferManager.h" +#include "VideoCommon/FrameDumper.h" #include "VideoCommon/GeometryShaderManager.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" +#include "VideoCommon/Present.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/TMEM.h" #include "VideoCommon/TextureCacheBase.h" @@ -95,6 +98,14 @@ void VideoCommon_DoState(PointerWrap& p) g_renderer->DoState(p); p.DoMarker("Renderer"); + g_presenter->DoState(p); + g_frame_dumper->DoState(p); + p.DoMarker("Presenter"); + + g_bounding_box->DoState(p); + p.DoMarker("Bounding Box"); + + // Refresh state. if (p.IsReadMode()) {