From 32e5043b291158ada1615a2e69ad2d6c142482c6 Mon Sep 17 00:00:00 2001 From: magumagu Date: Fri, 2 May 2014 00:08:44 -0700 Subject: [PATCH] WIP XFB scaling. Still an ugly mess. --- Source/Core/Core/HW/VideoInterface.cpp | 5 +++-- Source/Core/VideoBackends/D3D/Render.cpp | 2 +- Source/Core/VideoBackends/D3D/Render.h | 2 +- Source/Core/VideoBackends/OGL/Render.cpp | 18 ++++++++++-------- Source/Core/VideoBackends/OGL/Render.h | 2 +- Source/Core/VideoBackends/Software/SWmain.cpp | 2 +- .../Core/VideoBackends/Software/VideoBackend.h | 2 +- Source/Core/VideoCommon/MainBase.cpp | 8 +++++--- Source/Core/VideoCommon/RenderBase.cpp | 6 +++--- Source/Core/VideoCommon/RenderBase.h | 4 ++-- Source/Core/VideoCommon/VideoBackendBase.h | 4 ++-- 11 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Source/Core/Core/HW/VideoInterface.cpp b/Source/Core/Core/HW/VideoInterface.cpp index d559bf7c02..0fafd38f48 100644 --- a/Source/Core/Core/HW/VideoInterface.cpp +++ b/Source/Core/Core/HW/VideoInterface.cpp @@ -516,7 +516,8 @@ static void BeginField(FieldType field) // What should actually happen is that we should pass on the correct width, // stride, and height to the video backend, and it should deinterlace the // output when appropriate. - u32 fbWidth = m_PictureConfiguration.STD * (field == FIELD_PROGRESSIVE ? 16 : 8); + u32 fbStride = m_PictureConfiguration.STD * (field == FIELD_PROGRESSIVE ? 16 : 8); + u32 fbWidth = m_PictureConfiguration.WPL * 16; u32 fbHeight = m_VerticalTimingRegister.ACV * (field == FIELD_PROGRESSIVE ? 1 : 2); u32 xfbAddr; @@ -550,7 +551,7 @@ static void BeginField(FieldType field) m_VerticalTimingRegister.ACV, fieldTypeNames[field]); if (xfbAddr) - g_video_backend->Video_BeginField(xfbAddr, fbWidth, fbHeight); + g_video_backend->Video_BeginField(xfbAddr, fbWidth, fbStride, fbHeight); } static void EndField() diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 09d0af5b65..2f077cdbbd 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -709,7 +709,7 @@ void formatBufferDump(const u8* in, u8* out, int w, int h, int p) } // This function has the final picture. We adjust the aspect ratio here. -void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) +void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 175d521ca2..9448a85e03 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -40,7 +40,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override; - void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma) override; + void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) override; void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index dd64a42165..912624acd1 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1359,7 +1359,7 @@ static void DumpFrame(const std::vector& data, int w, int h) } // This function has the final picture. We adjust the aspect ratio here. -void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) +void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) { static int w = 0, h = 0; if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) @@ -1370,7 +1370,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl } u32 xfbCount = 0; - const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, xfbCount); if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0)) { DumpFrame(frame_data, w, h); @@ -1426,14 +1426,14 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl // use virtual xfb with offset int xfbHeight = xfbSource->srcHeight; int xfbWidth = xfbSource->srcWidth; - int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); + int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbStride * 2); MathUtil::Rectangle rect_u32; rect_u32.top = flipped_trc.top - hOffset * flipped_trc.GetHeight() / fbHeight; rect_u32.bottom = flipped_trc.top - (hOffset + xfbHeight) * flipped_trc.GetHeight() / fbHeight; - rect_u32.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbWidth)/2; - rect_u32.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbWidth)/2; + rect_u32.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbStride)/2; + rect_u32.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbStride)/2; drawRc.top = static_cast(rect_u32.top); drawRc.bottom = static_cast(rect_u32.bottom); @@ -1458,6 +1458,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl sourceRc.top = xfbSource->sourceRc.top; sourceRc.bottom = xfbSource->sourceRc.bottom; + sourceRc.right -= fbStride - fbWidth; + xfbSource->Draw(sourceRc, drawRc); } } @@ -1603,16 +1605,16 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl } // Finish up the current frame, print some stats - SetWindowSize(fbWidth, fbHeight); + SetWindowSize(fbStride, fbHeight); GLInterface->Update(); // just updates the render window position and the backbuffer size bool xfbchanged = false; - if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) + if (FramebufferManagerBase::LastXfbWidth() != fbStride || FramebufferManagerBase::LastXfbHeight() != fbHeight) { xfbchanged = true; - unsigned int const last_w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; + unsigned int const last_w = (fbStride < 1 || fbStride > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbStride; unsigned int const last_h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; FramebufferManagerBase::SetLastXfbWidth(last_w); FramebufferManagerBase::SetLastXfbHeight(last_h); diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 6ff9dc54eb..de51ed3ee7 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -76,7 +76,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) override; - void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma) override; + void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) override; void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) override; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index a6b9f509c9..e1b0f48380 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -201,7 +201,7 @@ void VideoSoftware::Video_Prepare() } // Run from the CPU thread (from VideoInterface.cpp) -void VideoSoftware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbHeight) +void VideoSoftware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight) { s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.fbWidth = fbWidth; diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h index 4ade7bed9a..eb4d4807c2 100644 --- a/Source/Core/VideoBackends/Software/VideoBackend.h +++ b/Source/Core/VideoBackends/Software/VideoBackend.h @@ -27,7 +27,7 @@ class VideoSoftware : public VideoBackend void Video_EnterLoop() override; void Video_ExitLoop() override; - void Video_BeginField(u32, u32, u32) override; + void Video_BeginField(u32, u32, u32, u32) override; void Video_EndField() override; u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override; diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 97a2f5d017..aa08c932e7 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -29,6 +29,7 @@ static volatile struct { u32 xfbAddr; u32 fbWidth; + u32 fbStride; u32 fbHeight; } s_beginFieldArgs; @@ -74,7 +75,7 @@ static void VideoFifo_CheckSwapRequest() if (s_swapRequested.IsSet()) { EFBRectangle rc; - Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); + Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbStride, s_beginFieldArgs.fbHeight, rc); s_swapRequested.Clear(); } } @@ -90,7 +91,7 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) u32 aLower = xfbAddr; u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight; u32 bLower = s_beginFieldArgs.xfbAddr; - u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight; + u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbStride * s_beginFieldArgs.fbHeight; if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) VideoFifo_CheckSwapRequest(); @@ -99,7 +100,7 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) } // Run from the CPU thread (from VideoInterface.cpp) -void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbHeight) +void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight) { if (s_BackendInitialized && g_ActiveConfig.bUseXFB) { @@ -107,6 +108,7 @@ void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbHeig VideoFifo_CheckSwapRequest(); s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.fbWidth = fbWidth; + s_beginFieldArgs.fbStride = fbStride; s_beginFieldArgs.fbHeight = fbHeight; } } diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 51f25d7880..726efea803 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -122,7 +122,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbWidt } else { - Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma); + Swap(xfbAddr, fbWidth, fbWidth, fbHeight, sourceRc, Gamma); s_swapRequested.Clear(); } } @@ -514,10 +514,10 @@ void Renderer::RecordVideoMemory() FifoRecorder::GetInstance().SetVideoMemory(bpmem_ptr, cpmem, xfmem_ptr, xfregs_ptr, xfregs_size); } -void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc, float Gamma) +void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) { // TODO: merge more generic parts into VideoCommon - g_renderer->SwapImpl(xfbAddr, fbWidth, fbHeight, rc, Gamma); + g_renderer->SwapImpl(xfbAddr, fbWidth, fbStride, fbHeight, rc, Gamma); if (XFBWrited) g_renderer->m_fps_counter.Update(); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index fe4adf449e..2cd2f03356 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -109,8 +109,8 @@ public: virtual void RestoreAPIState() = 0; // Finish up the current frame, print some stats - static void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f); - virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0; + static void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f); + virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma = 1.0f) = 0; virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0; diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h index b1fe931888..6ab9fce8f2 100644 --- a/Source/Core/VideoCommon/VideoBackendBase.h +++ b/Source/Core/VideoCommon/VideoBackendBase.h @@ -84,7 +84,7 @@ public: virtual void Video_ExitLoop() = 0; virtual void Video_Cleanup() = 0; // called from gl/d3d thread - virtual void Video_BeginField(u32, u32, u32) = 0; + virtual void Video_BeginField(u32, u32, u32, u32) = 0; virtual void Video_EndField() = 0; virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0; @@ -130,7 +130,7 @@ class VideoBackendHardware : public VideoBackend void Video_EnterLoop() override; void Video_ExitLoop() override; - void Video_BeginField(u32, u32, u32) override; + void Video_BeginField(u32, u32, u32, u32) override; void Video_EndField() override; u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override;