From 159ed43f677ed62097569244882c0a9ddffa7a67 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 18 Nov 2010 02:21:26 +0000 Subject: [PATCH] Move some shared gfx plugin code into VideoCommon. Changed "Renderer" class to use virtual functions. (setting stuff up for video plugin merging) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6433 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/VideoCommon/CMakeLists.txt | 3 + .../VideoCommon}/Src/BPFunctions.cpp | 31 +- Source/Core/VideoCommon/Src/BPStructs.cpp | 2 +- .../Src/FramebufferManagerBase.cpp | 8 +- .../VideoCommon/Src/FramebufferManagerBase.h | 4 +- Source/Core/VideoCommon/Src/MainBase.cpp | 214 ++++++++++ Source/Core/VideoCommon/Src/MainBase.h | 15 + .../Core/VideoCommon/Src/OnScreenDisplay.cpp | 6 +- Source/Core/VideoCommon/Src/Render.h | 100 ----- Source/Core/VideoCommon/Src/RenderBase.cpp | 264 ++++++++++++ Source/Core/VideoCommon/Src/RenderBase.h | 165 ++++++++ Source/Core/VideoCommon/Src/SConscript | 2 + .../Core/VideoCommon/Src/TextureCacheBase.cpp | 6 +- .../VideoCommon/Src/VertexManagerBase.cpp | 2 +- Source/Core/VideoCommon/Src/VideoCommon.h | 9 +- Source/Core/VideoCommon/VideoCommon.vcproj | 24 +- Source/Dolphin.sln | 3 - .../Plugin_VideoDX11/Plugin_VideoDX11.vcproj | 12 +- .../Plugin_VideoDX11/Src/BPFunctions.cpp | 138 ------- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 354 ++++------------ Source/Plugins/Plugin_VideoDX11/Src/Render.h | 49 +++ .../Plugin_VideoDX11/Src/TextureCache.cpp | 6 +- .../Plugin_VideoDX11/Src/VertexManager.cpp | 2 +- Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 206 +--------- Source/Plugins/Plugin_VideoDX11/Src/main.h | 4 +- .../Plugin_VideoDX9/Plugin_VideoDX9.vcproj | 12 +- .../Src/FramebufferManager.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 372 ++++------------- Source/Plugins/Plugin_VideoDX9/Src/Render.h | 49 +++ .../Plugin_VideoDX9/Src/TextureCache.cpp | 2 +- .../Plugin_VideoDX9/Src/TextureConverter.cpp | 12 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 212 +--------- Source/Plugins/Plugin_VideoDX9/Src/main.h | 4 +- .../Plugin_VideoOGL/Plugin_VideoOGL.vcproj | 8 +- .../Plugin_VideoOGL/Src/BPFunctions.cpp | 140 ------- .../Src/FramebufferManager.cpp | 6 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 387 ++++-------------- Source/Plugins/Plugin_VideoOGL/Src/Render.h | 49 +++ Source/Plugins/Plugin_VideoOGL/Src/SConscript | 1 - .../Plugin_VideoOGL/Src/TextureCache.cpp | 2 +- .../Plugin_VideoOGL/Src/TextureConverter.cpp | 12 +- .../Plugin_VideoOGL/Src/VertexManager.cpp | 8 +- Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 226 +--------- Source/Plugins/Plugin_VideoOGL/Src/main.h | 4 +- 45 files changed, 1180 insertions(+), 1959 deletions(-) rename Source/{Plugins/Plugin_VideoDX9 => Core/VideoCommon}/Src/BPFunctions.cpp (84%) create mode 100644 Source/Core/VideoCommon/Src/MainBase.cpp create mode 100644 Source/Core/VideoCommon/Src/MainBase.h delete mode 100644 Source/Core/VideoCommon/Src/Render.h create mode 100644 Source/Core/VideoCommon/Src/RenderBase.cpp create mode 100644 Source/Core/VideoCommon/Src/RenderBase.h delete mode 100644 Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp create mode 100644 Source/Plugins/Plugin_VideoDX11/Src/Render.h create mode 100644 Source/Plugins/Plugin_VideoDX9/Src/Render.h delete mode 100644 Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/Render.h diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 4b5b39dfce..3692d120d1 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -1,4 +1,5 @@ set(SRCS Src/BPMemory.cpp + Src/BPFunctions.cpp Src/BPStructs.cpp Src/CommandProcessor.cpp Src/CPMemory.cpp @@ -8,6 +9,7 @@ set(SRCS Src/BPMemory.cpp Src/HiresTextures.cpp Src/ImageWrite.cpp Src/IndexGenerator.cpp + Src/MainBase.cpp Src/memcpy_amd.cpp Src/OnScreenDisplay.cpp Src/OpcodeDecoding.cpp @@ -15,6 +17,7 @@ set(SRCS Src/BPMemory.cpp Src/PixelShaderGen.cpp Src/PixelShaderManager.cpp Src/Profiler.cpp + Src/RenderBase.cpp Src/Statistics.cpp Src/TextureCacheBase.cpp Src/TextureConversionShader.cpp diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp b/Source/Core/VideoCommon/Src/BPFunctions.cpp similarity index 84% rename from Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp rename to Source/Core/VideoCommon/Src/BPFunctions.cpp index 178c0e4e63..9e2c99b6db 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp +++ b/Source/Core/VideoCommon/Src/BPFunctions.cpp @@ -17,18 +17,15 @@ #include "BPFunctions.h" #include "Common.h" -#include "D3DBase.h" -#include "Debugger/Debugger.h" -#include "TextureCache.h" -#include "VertexManager.h" +#include "RenderBase.h" +#include "TextureCacheBase.h" +#include "VertexManagerBase.h" #include "VertexShaderManager.h" #include "VideoConfig.h" bool textureChanged[8]; const bool renderFog = false; -using namespace D3D; - namespace BPFunctions { // ---------------------------------------------- @@ -44,40 +41,40 @@ void FlushPipeline() void SetGenerationMode(const BPCmd &bp) { - Renderer::SetGenerationMode(); + g_renderer->SetGenerationMode(); } void SetScissor(const BPCmd &bp) { - Renderer::SetScissorRect(); + g_renderer->SetScissorRect(); } void SetLineWidth(const BPCmd &bp) { - Renderer::SetLineWidth(); + g_renderer->SetLineWidth(); } void SetDepthMode(const BPCmd &bp) { - Renderer::SetDepthMode(); + g_renderer->SetDepthMode(); } void SetBlendMode(const BPCmd &bp) { - Renderer::SetBlendMode(false); + g_renderer->SetBlendMode(false); } void SetDitherMode(const BPCmd &bp) { - Renderer::SetDitherMode(); + g_renderer->SetDitherMode(); } void SetLogicOpMode(const BPCmd &bp) { - Renderer::SetLogicOpMode(); + g_renderer->SetLogicOpMode(); } void SetColorMask(const BPCmd &bp) { - Renderer::SetColorMask(); + g_renderer->SetColorMask(); } void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf) @@ -100,13 +97,13 @@ void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; u32 z = bpmem.clearZValue; - Renderer::ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z); + g_renderer->ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z); } } void RestoreRenderState(const BPCmd &bp) { - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } bool GetConfig(const int &type) @@ -132,7 +129,7 @@ u8 *GetPointer(const u32 &address) void SetTextureMode(const BPCmd &bp) { - Renderer::SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0); + g_renderer->SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0); } void SetInterlacingMode(const BPCmd &bp) diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index d6709e20e3..f1de8f8b6c 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -20,7 +20,7 @@ #include "VideoConfig.h" #include "Profiler.h" #include "Statistics.h" -#include "Render.h" +#include "RenderBase.h" #include "VideoCommon.h" #include "PixelShaderManager.h" #include "PixelEngine.h" diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp index bfb5c3b3d6..4b0f23844d 100644 --- a/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp @@ -1,7 +1,7 @@ #include "FramebufferManagerBase.h" -#include "Render.h" +#include "RenderBase.h" #include "VideoConfig.h" FramebufferManagerBase *g_framebuffer_manager; @@ -154,17 +154,17 @@ void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHe vxfb->xfbSource->srcWidth = vxfb->xfbWidth = fbWidth; vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight; - vxfb->xfbSource->sourceRc = Renderer::ConvertEFBRectangle(sourceRc); + vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc); // keep stale XFB data from being used ReplaceVirtualXFB(); - Renderer::ResetAPIState(); // reset any game specific settings + g_renderer->ResetAPIState(); // reset any game specific settings // Copy EFB data to XFB and restore render target again vxfb->xfbSource->CopyEFB(); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height) diff --git a/Source/Core/VideoCommon/Src/FramebufferManagerBase.h b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h index 14f2af1b51..7f83c2386e 100644 --- a/Source/Core/VideoCommon/Src/FramebufferManagerBase.h +++ b/Source/Core/VideoCommon/Src/FramebufferManagerBase.h @@ -1,6 +1,6 @@ -#ifndef _FRAMEBUFFERMANAGER_H -#define _FRAMEBUFFERMANAGER_H +#ifndef _FRAMEBUFFERMANAGERBASE_H +#define _FRAMEBUFFERMANAGERBASE_H #include diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp new file mode 100644 index 0000000000..f9981b6a65 --- /dev/null +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -0,0 +1,214 @@ + +#include "MainBase.h" +#include "VideoState.h" +#include "VideoConfig.h" +#include "RenderBase.h" +#include "FramebufferManagerBase.h" +#include "TextureCacheBase.h" +#include "CommandProcessor.h" +#include "PixelEngine.h" +#include "Atomic.h" +#include "Fifo.h" +#include "OnScreenDisplay.h" + +bool s_PluginInitialized = false; + +volatile u32 s_swapRequested = false; +u32 s_efbAccessRequested = false; +volatile u32 s_FifoShuttingDown = false; + +static volatile struct +{ + u32 xfbAddr; + FieldType field; + u32 fbWidth; + u32 fbHeight; +} s_beginFieldArgs; + +static volatile EFBAccessType s_AccessEFBType; + +static struct +{ + EFBAccessType type; + u32 x; + u32 y; + u32 Data; +} s_accessEFBArgs; + +static u32 s_AccessEFBResult = 0; + + +void EmuStateChange(PLUGIN_EMUSTATE newState) +{ + Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); +} + +// Enter and exit the video loop +void Video_EnterLoop() +{ + Fifo_EnterLoop(g_VideoInitialize); +} + +void Video_ExitLoop() +{ + Fifo_ExitLoop(); + s_FifoShuttingDown = true; +} + +void Video_SetRendering(bool bEnabled) +{ + Fifo_SetRendering(bEnabled); +} + +// Run from the graphics thread (from Fifo.cpp) +void VideoFifo_CheckSwapRequest() +{ + if(g_ActiveConfig.bUseXFB) + { + if (Common::AtomicLoadAcquire(s_swapRequested)) + { + EFBRectangle rc; + g_renderer->Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); + Common::AtomicStoreRelease(s_swapRequested, FALSE); + } + } +} + +// Run from the graphics thread (from Fifo.cpp) +void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) +{ + if (g_ActiveConfig.bUseXFB) + { + if(Common::AtomicLoadAcquire(s_swapRequested)) + { + 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; + + if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) + VideoFifo_CheckSwapRequest(); + } + } +} + +// Run from the CPU thread (from VideoInterface.cpp) +void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) +{ + if (s_PluginInitialized && g_ActiveConfig.bUseXFB) + { + if (!g_VideoInitialize.bOnThread) + VideoFifo_CheckSwapRequest(); + s_beginFieldArgs.xfbAddr = xfbAddr; + s_beginFieldArgs.field = field; + s_beginFieldArgs.fbWidth = fbWidth; + s_beginFieldArgs.fbHeight = fbHeight; + } +} + +// Run from the CPU thread (from VideoInterface.cpp) +void Video_EndField() +{ + if (s_PluginInitialized) + { + Common::AtomicStoreRelease(s_swapRequested, TRUE); + } +} + +void Video_AddMessage(const char* pstr, u32 milliseconds) +{ + OSD::AddMessage(pstr, milliseconds); +} + +// Screenshot +void Video_Screenshot(const char *_szFilename) +{ + Renderer::SetScreenshot(_szFilename); +} + +void VideoFifo_CheckEFBAccess() +{ + if (Common::AtomicLoadAcquire(s_efbAccessRequested)) + { + s_AccessEFBResult = g_renderer->AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data); + + Common::AtomicStoreRelease(s_efbAccessRequested, FALSE); + } +} + +u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) +{ + if (s_PluginInitialized) + { + s_accessEFBArgs.type = type; + s_accessEFBArgs.x = x; + s_accessEFBArgs.y = y; + s_accessEFBArgs.Data = InputData; + + Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); + + if (g_VideoInitialize.bOnThread) + { + while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown) + //Common::SleepCurrentThread(1); + Common::YieldCPU(); + } + else + VideoFifo_CheckEFBAccess(); + + return s_AccessEFBResult; + } + + return 0; +} + +void VideoFifo_CheckAsyncRequest() +{ + VideoFifo_CheckSwapRequest(); + VideoFifo_CheckEFBAccess(); +} + +void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) +{ + CommandProcessor::Read16(_rReturnValue, _Address); +} + +void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address) +{ + CommandProcessor::Write16(_Data, _Address); +} + +void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address) +{ + PixelEngine::Read16(_rReturnValue, _Address); +} + +void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address) +{ + PixelEngine::Write16(_Data, _Address); +} + +void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address) +{ + PixelEngine::Write32(_Data, _Address); +} + +void Video_GatherPipeBursted(void) +{ + CommandProcessor::GatherPipeBursted(); +} + +void Video_WaitForFrameFinish(void) +{ + CommandProcessor::WaitForFrameFinish(); +} + +bool Video_IsFifoBusy(void) +{ + return CommandProcessor::isFifoBusy; +} + +void Video_AbortFrame(void) +{ + CommandProcessor::AbortFrame(); +} diff --git a/Source/Core/VideoCommon/Src/MainBase.h b/Source/Core/VideoCommon/Src/MainBase.h new file mode 100644 index 0000000000..f04f8b0213 --- /dev/null +++ b/Source/Core/VideoCommon/Src/MainBase.h @@ -0,0 +1,15 @@ + +#ifndef _VIDEOCOMMON_MAINBASE_H_ +#define _VIDEOCOMMON_MAINBASE_H_ + +#include "CommonTypes.h" + +extern bool s_PluginInitialized; +extern u32 s_efbAccessRequested; +extern volatile u32 s_FifoShuttingDown; +extern volatile u32 s_swapRequested; + +void VideoFifo_CheckEFBAccess(); +void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); + +#endif \ No newline at end of file diff --git a/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp b/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp index b172e7390c..d91806b3ce 100644 --- a/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp +++ b/Source/Core/VideoCommon/Src/OnScreenDisplay.cpp @@ -20,7 +20,7 @@ #include "Common.h" #include "OnScreenDisplay.h" -#include "Render.h" +#include "RenderBase.h" #include "Timer.h" namespace OSD @@ -64,8 +64,8 @@ void DrawMessages() alpha <<= 24; - Renderer::RenderText(it->str, left+1, top+1, 0x000000|alpha); - Renderer::RenderText(it->str, left, top, 0xffff30|alpha); + g_renderer->RenderText(it->str, left+1, top+1, 0x000000|alpha); + g_renderer->RenderText(it->str, left, top, 0xffff30|alpha); top += 15; if (time_left <= 0) diff --git a/Source/Core/VideoCommon/Src/Render.h b/Source/Core/VideoCommon/Src/Render.h deleted file mode 100644 index 53ae09c4c6..0000000000 --- a/Source/Core/VideoCommon/Src/Render.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -// --------------------------------------------------------------------------------------------- -// GC graphics pipeline -// --------------------------------------------------------------------------------------------- -// 3d commands are issued through the fifo. The gpu draws to the 2MB EFB. -// The efb can be copied back into ram in two forms: as textures or as XFB. -// The XFB is the region in RAM that the VI chip scans out to the television. -// So, after all rendering to EFB is done, the image is copied into one of two XFBs in RAM. -// Next frame, that one is scanned out and the other one gets the copy. = double buffering. -// --------------------------------------------------------------------------------------------- - -#ifndef _COMMON_RENDER_H_ -#define _COMMON_RENDER_H_ - -#include "VideoCommon.h" -#include "MathUtil.h" -#include "pluginspecs_video.h" - -// TODO: Move these out of here. -extern int frameCount; -extern int OSDChoice, OSDTime, OSDInternalW, OSDInternalH; - -// Renderer really isn't a very good name for this class - it's more like "Misc". -// The long term goal is to get rid of this class and replace it with others that make -// more sense. -class Renderer -{ -public: - static bool Init(); - static void Shutdown(); - - // What's the real difference between these? Too similar names. - static void ResetAPIState(); - static void RestoreAPIState(); - - static void SetColorMask(); - static void SetBlendMode(bool forceUpdate); - static bool SetScissorRect(); - static void SetGenerationMode(); - static void SetDepthMode(); - static void SetLogicOpMode(); - static void SetDitherMode(); - static void SetLineWidth(); - static void SetSamplerState(int stage,int texindex); - static void SetInterlacingMode(); - - // Render target management - static int GetFrameBufferWidth(); - static int GetFrameBufferHeight(); - static int GetCustomWidth(); - static int GetCustomHeight(); - static int GetTargetWidth(); - static int GetTargetHeight(); - static int GetFullTargetWidth(); - static int GetFullTargetHeight(); - - // Multiply any 2D EFB coordinates by these when rendering. - static float GetTargetScaleX(); - static float GetTargetScaleY(); - - static float GetXFBScaleX(); - static float GetXFBScaleY(); - - static TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); - - static u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); - - // Random utilities - static void RenderText(const char* pstr, int left, int top, u32 color); - static void DrawDebugText(); - static void SetScreenshot(const char *filename); - static void FlipImageData(u8 *data, int w, int h); - static bool SaveRenderTarget(const char *filename, TargetRectangle back_rc); - - static void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); - static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); - - // Finish up the current frame, print some stats - static void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc); -}; - -void UpdateViewport(); - -#endif // _COMMON_RENDER_H_ diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp new file mode 100644 index 0000000000..d4b90bc802 --- /dev/null +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -0,0 +1,264 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// --------------------------------------------------------------------------------------------- +// GC graphics pipeline +// --------------------------------------------------------------------------------------------- +// 3d commands are issued through the fifo. The gpu draws to the 2MB EFB. +// The efb can be copied back into ram in two forms: as textures or as XFB. +// The XFB is the region in RAM that the VI chip scans out to the television. +// So, after all rendering to EFB is done, the image is copied into one of two XFBs in RAM. +// Next frame, that one is scanned out and the other one gets the copy. = double buffering. +// --------------------------------------------------------------------------------------------- + + +#include "RenderBase.h" +#include "Atomic.h" +#include "MainBase.h" +#include "VideoConfig.h" +#include "FramebufferManagerBase.h" +#include "Fifo.h" +#include "Timer.h" +#include "StringUtil.h" + +#include +#include + +// TODO: Move these out of here. +int frameCount; +//int OSDChoice, OSDTime, OSDInternalW, OSDInternalH; + +SVideoInitialize g_VideoInitialize; +PLUGIN_GLOBALS* globals; + +Renderer *g_renderer; + +bool s_bLastFrameDumped = false; +Common::CriticalSection Renderer::s_criticalScreenshot; +std::string Renderer::s_sScreenshotName; + +volatile bool Renderer::s_bScreenshot; + +// The framebuffer size +int Renderer::s_target_width; +int Renderer::s_target_height; + +// The custom resolution +int Renderer::s_Fulltarget_width; +int Renderer::s_Fulltarget_height; + +// TODO: Add functionality to reinit all the render targets when the window is resized. +int Renderer::s_backbuffer_width; +int Renderer::s_backbuffer_height; + +// Internal resolution scale (related to xScale/yScale for "Auto" scaling) +float Renderer::EFBxScale; +float Renderer::EFByScale; + +// ratio of backbuffer size and render area size +float Renderer::xScale; +float Renderer::yScale; + +unsigned int Renderer::s_XFB_width; +unsigned int Renderer::s_XFB_height; + +int Renderer::s_LastEFBScale; + +bool Renderer::s_skipSwap; +bool Renderer::XFBWrited; + +Renderer::Renderer() +{ + UpdateActiveConfig(); +} + +Renderer::~Renderer() +{ + +} + +void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +{ + if (!fbWidth || !fbHeight) + return; + + s_skipSwap = g_bSkipCurrentFrame; + + VideoFifo_CheckEFBAccess(); + VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); + XFBWrited = true; + + // XXX: Without the VI, how would we know what kind of field this is? So + // just use progressive. + if (g_ActiveConfig.bUseXFB) + { + FramebufferManagerBase::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + } + else + { + g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc); + Common::AtomicStoreRelease(s_swapRequested, FALSE); + } +} + +// return true if target size changed +bool Renderer::CalculateTargetSize(float multiplier) +{ + switch (s_LastEFBScale) + { + case 0: + EFBxScale = xScale; + EFByScale = yScale; + break; + case 1: + EFBxScale = ceilf(xScale); + EFByScale = ceilf(yScale); + break; + default: + EFBxScale = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); + break; + }; + + EFBxScale *= multiplier; + EFByScale *= multiplier; + + const int m_newFrameBufferWidth = (int)(EFB_WIDTH * EFBxScale); + const int m_newFrameBufferHeight = (int)(EFB_HEIGHT * EFByScale); + + if (m_newFrameBufferWidth != s_target_width || + m_newFrameBufferHeight != s_target_height) + { + s_Fulltarget_width = s_target_width = m_newFrameBufferWidth; + s_Fulltarget_height = s_target_height = m_newFrameBufferHeight; + + return true; + } + + return false; +} + +void Renderer::SetScreenshot(const char *filename) +{ + s_criticalScreenshot.Enter(); + s_sScreenshotName = filename; + s_bScreenshot = true; + s_criticalScreenshot.Leave(); +} + +// Create On-Screen-Messages +void Renderer::DrawDebugText() +{ + // OSD Menu messages + if (g_ActiveConfig.bOSDHotKey) + { + if (OSDChoice > 0) + { + OSDTime = Common::Timer::GetTimeMs() + 3000; + OSDChoice = -OSDChoice; + } + if ((u32)OSDTime > Common::Timer::GetTimeMs()) + { + const char* res_text = ""; + switch (g_ActiveConfig.iEFBScale) + { + case 0: + res_text = "Auto (fractional)"; + break; + case 1: + res_text = "Auto (integral)"; + break; + case 2: + res_text = "Native"; + break; + case 3: + res_text = "2x"; + break; + case 4: + res_text = "3x"; + break; + } + + const char* ar_text = ""; + switch(g_ActiveConfig.iAspectRatio) + { + case ASPECT_AUTO: + ar_text = "Auto"; + break; + case ASPECT_FORCE_16_9: + ar_text = "16:9"; + break; + case ASPECT_FORCE_4_3: + ar_text = "4:3"; + break; + case ASPECT_STRETCH: + ar_text = "Stretch"; + break; + } + + const char* const efbcopy_text = g_ActiveConfig.bEFBCopyDisable ? "Disabled" : + g_ActiveConfig.bCopyEFBToTexture ? "to Texture" : "to RAM"; + + // The rows + const std::string lines[] = + { + std::string("3: Internal Resolution: ") + res_text, + std::string("4: Aspect Ratio: ") + ar_text + (g_ActiveConfig.bCrop ? " (crop)" : ""), + std::string("5: Copy EFB: ") + efbcopy_text, + std::string("6: Fog: ") + (g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"), + std::string("7: Material Lighting: ") + (g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled"), + }; + + enum { lines_count = sizeof(lines)/sizeof(*lines) }; + + std::string final_yellow, final_cyan; + + // If there is more text than this we will have a collision + if (g_ActiveConfig.bShowFPS) + { + final_yellow = final_cyan = "\n\n"; + } + + // The latest changed setting in yellow + for (int i = 0; i != lines_count; ++i) + { + if (OSDChoice == -i - 1) + final_yellow += lines[i]; + final_yellow += '\n'; + } + + // The other settings in cyan + for (int i = 0; i != lines_count; ++i) + { + if (OSDChoice != -i - 1) + final_cyan += lines[i]; + final_cyan += '\n'; + } + + // Render a shadow + g_renderer->RenderText(final_cyan.c_str(), 21, 21, 0xDD000000); + g_renderer->RenderText(final_yellow.c_str(), 21, 21, 0xDD000000); + //and then the text + g_renderer->RenderText(final_cyan.c_str(), 20, 20, 0xFF00FFFF); + g_renderer->RenderText(final_yellow.c_str(), 20, 20, 0xFFFFFF00); + } + } +} + +void UpdateViewport() +{ + g_renderer->UpdateViewport(); +} diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h new file mode 100644 index 0000000000..15a4cb78b1 --- /dev/null +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -0,0 +1,165 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// --------------------------------------------------------------------------------------------- +// GC graphics pipeline +// --------------------------------------------------------------------------------------------- +// 3d commands are issued through the fifo. The gpu draws to the 2MB EFB. +// The efb can be copied back into ram in two forms: as textures or as XFB. +// The XFB is the region in RAM that the VI chip scans out to the television. +// So, after all rendering to EFB is done, the image is copied into one of two XFBs in RAM. +// Next frame, that one is scanned out and the other one gets the copy. = double buffering. +// --------------------------------------------------------------------------------------------- + +#ifndef _COMMON_RENDERBASE_H_ +#define _COMMON_RENDERBASE_H_ + +#include "VideoCommon.h" +#include "Thread.h" +#include "MathUtil.h" +#include "pluginspecs_video.h" +#include "NativeVertexFormat.h" +#include "FramebufferManagerBase.h" +#include "BPMemory.h" + +#include + +// TODO: Move these out of here. +extern int frameCount; +extern int OSDChoice, OSDTime, OSDInternalW, OSDInternalH; + +extern bool s_bLastFrameDumped; +extern SVideoInitialize g_VideoInitialize; +extern PLUGIN_GLOBALS* globals; + +// Renderer really isn't a very good name for this class - it's more like "Misc". +// The long term goal is to get rid of this class and replace it with others that make +// more sense. +class Renderer +{ +public: + Renderer(); + virtual ~Renderer(); + + virtual void SetColorMask() = 0; + virtual void SetBlendMode(bool forceUpdate) = 0; + virtual bool SetScissorRect() = 0; + virtual void SetGenerationMode() = 0; + virtual void SetDepthMode() = 0; + virtual void SetLogicOpMode() = 0; + virtual void SetDitherMode() = 0; + virtual void SetLineWidth() = 0; + virtual void SetSamplerState(int stage,int texindex) = 0; + virtual void SetInterlacingMode() = 0; + + // Return the rendering target width and height + static int GetTargetWidth() { return s_target_width; } + static int GetTargetHeight() { return s_target_height; } + + static int GetFullTargetWidth() { return s_Fulltarget_width; } + static int GetFullTargetHeight() { return s_Fulltarget_height; } + + // Multiply any 2D EFB coordinates by these when rendering. + static float GetTargetScaleX() { return EFBxScale; } + static float GetTargetScaleY() { return EFByScale; } + + static float GetXFBScaleX() { return xScale; } + static float GetXFBScaleY() { return yScale; } + + static int GetBackbufferWidth() { return s_backbuffer_width; } + static int GetBackbufferHeight() { return s_backbuffer_height; } + + virtual TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) = 0; + + // Random utilities + static void SetScreenshot(const char *filename); + static void DrawDebugText(); + + virtual void RenderText(const char* pstr, int left, int top, u32 color) = 0; + + virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0; + static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); + + virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0; + + // What's the real difference between these? Too similar names. + virtual void ResetAPIState() = 0; + virtual void RestoreAPIState() = 0; + + // Finish up the current frame, print some stats + virtual void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc) = 0; + + virtual void UpdateViewport() = 0; + + virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0; + +protected: + + static Common::CriticalSection s_criticalScreenshot; + static std::string s_sScreenshotName; + + static bool CalculateTargetSize(float multiplier = 1); + + static volatile bool s_bScreenshot; + + // The framebuffer size + static int s_target_width; + static int s_target_height; + + // The custom resolution + static int s_Fulltarget_width; + static int s_Fulltarget_height; + + // TODO: Add functionality to reinit all the render targets when the window is resized. + static int s_backbuffer_width; + static int s_backbuffer_height; + + // Internal resolution scale (related to xScale/yScale for "Auto" scaling) + static float EFBxScale; + static float EFByScale; + + // ratio of backbuffer size and render area size + static float xScale; + static float yScale; + + static unsigned int s_XFB_width; + static unsigned int s_XFB_height; + + // can probably eliminate this static var + static int s_LastEFBScale; + + static bool s_skipSwap; + static bool XFBWrited; +}; + +extern Renderer *g_renderer; + +void UpdateViewport(); + +template +void GetScissorRect(MathUtil::Rectangle &rect) +{ + const int xoff = bpmem.scissorOffset.x * 2 - 342; + const int yoff = bpmem.scissorOffset.y * 2 - 342; + + rect.left = (R)((float)bpmem.scissorTL.x - xoff - 342); + rect.top = (R)((float)bpmem.scissorTL.y - yoff - 342); + rect.right = (R)((float)bpmem.scissorBR.x - xoff - 341); + rect.bottom = (R)((float)bpmem.scissorBR.y - yoff - 341); +} + +#endif // _COMMON_RENDERBASE_H_ diff --git a/Source/Core/VideoCommon/Src/SConscript b/Source/Core/VideoCommon/Src/SConscript index a48e419957..a099cfa980 100644 --- a/Source/Core/VideoCommon/Src/SConscript +++ b/Source/Core/VideoCommon/Src/SConscript @@ -29,7 +29,9 @@ files = [ 'VertexLoader_TextCoord.cpp', 'TextureConversionShader.cpp', 'ImageWrite.cpp', + 'MainBase.cpp', 'FramebufferManagerBase.cpp', + 'RenderBase.cpp', 'VertexManagerBase.cpp', 'TextureCacheBase.cpp', 'Statistics.cpp', diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 65a74b71dc..f0a5f2d639 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -4,7 +4,7 @@ #include "VideoConfig.h" #include "Statistics.h" #include "HiresTextures.h" -#include "Render.h" +#include "RenderBase.h" #include "FileUtil.h" #include "Profiler.h" @@ -668,9 +668,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, entry->frameCount = frameCount; - Renderer::ResetAPIState(); // reset any game specific settings + g_renderer->ResetAPIState(); // reset any game specific settings entry->FromRenderTarget(bFromZBuffer, bScaleByHalf, cbufid, colmat, source_rect, bIsIntensityFmt, copyfmt); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index b41c2ab30f..c8d908447a 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -8,7 +8,7 @@ #include "PixelShaderManager.h" #include "NativeVertexFormat.h" #include "TextureCacheBase.h" -#include "Render.h" +#include "RenderBase.h" #include "Profiler.h" #include "VertexManagerBase.h" diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index cb79d92d7a..f3737729f3 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -59,7 +59,6 @@ enum extern SVideoInitialize g_VideoInitialize; - inline u8 *Memory_GetPtr(u32 _uAddress) { return g_VideoInitialize.pGetMemoryPointer(_uAddress); @@ -123,10 +122,16 @@ struct TargetRectangle : public MathUtil::Rectangle { #ifdef _WIN32 // Only used by D3D plugin. - const RECT *AsRECT() const { + const RECT *AsRECT() const + { // The types are binary compatible so this works. return (const RECT *)this; } + RECT *AsRECT() + { + // The types are binary compatible so this works. + return (RECT *)this; + } #endif }; diff --git a/Source/Core/VideoCommon/VideoCommon.vcproj b/Source/Core/VideoCommon/VideoCommon.vcproj index b023fd13bd..bdee37f7ec 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcproj +++ b/Source/Core/VideoCommon/VideoCommon.vcproj @@ -458,6 +458,10 @@ + + @@ -738,6 +742,22 @@ RelativePath=".\Src\FramebufferManagerBase.h" > + + + + + + + + @@ -779,10 +799,6 @@ RelativePath=".\Src\PixelEngine.h" > - - diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index 0e007d0e7f..55b034b805 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -63,13 +63,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Commo EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}" ProjectSection(ProjectDependencies) = postProject - {21DBE606-2958-43AC-A14E-B6B798D56554} = {21DBE606-2958-43AC-A14E-B6B798D56554} {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA} - {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160} = {CFDCEE0E-FA45-4F72-9FCC-0B88F5A75160} {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8} = {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8} {D4833C30-FA5F-4DFE-BD32-109DE1F09ED1} = {D4833C30-FA5F-4DFE-BD32-109DE1F09ED1} {05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75} - {636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18} = {636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18} {33546D62-7F34-4EA6-A88E-D538B36E16BF} = {33546D62-7F34-4EA6-A88E-D538B36E16BF} {11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED} {3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63} diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj index d28b04f0b2..6acf8fc07c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcproj @@ -739,6 +739,10 @@ RelativePath=".\Src\Render.cpp" > + + @@ -816,14 +820,6 @@ > - - - - diff --git a/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp deleted file mode 100644 index f7428935f7..0000000000 --- a/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "BPFunctions.h" -#include "Common.h" -#include "D3DBase.h" -#include "Render.h" -#include "TextureCache.h" -#include "VertexManager.h" -#include "VertexShaderManager.h" -#include "VideoConfig.h" - -namespace BPFunctions -{ -// ---------------------------------------------- -// State translation lookup tables -// Reference: Yet Another Gamecube Documentation -// ---------------------------------------------- - - -void FlushPipeline() -{ - VertexManager::Flush(); -} - -void SetGenerationMode(const BPCmd &bp) -{ - Renderer::SetGenerationMode(); -} - -void SetScissor(const BPCmd &bp) -{ - Renderer::SetScissorRect(); -} - -void SetLineWidth(const BPCmd &bp) -{ - Renderer::SetLineWidth(); -} - -void SetDepthMode(const BPCmd &bp) -{ - Renderer::SetDepthMode(); -} - -void SetBlendMode(const BPCmd &bp) -{ - Renderer::SetBlendMode(false); -} -void SetDitherMode(const BPCmd &bp) -{ - Renderer::SetDitherMode(); -} -void SetLogicOpMode(const BPCmd &bp) -{ - Renderer::SetLogicOpMode(); -} - -void SetColorMask(const BPCmd &bp) -{ - Renderer::SetColorMask(); -} - -void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf) -{ - // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) - if (!g_ActiveConfig.bEFBCopyDisable) - { - TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, !!scaleByHalf, rc); - } -} - -void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) -{ - bool colorEnable = bpmem.blendmode.colorupdate; - bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate); - bool zEnable = bpmem.zmode.updateenable; - - if (colorEnable || alphaEnable || zEnable) - { - u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; - u32 z = bpmem.clearZValue; - - Renderer::ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z); - } -} - -void RestoreRenderState(const BPCmd &bp) -{ - Renderer::RestoreAPIState(); -} - -bool GetConfig(const int &type) -{ - switch (type) - { - case CONFIG_ISWII: - return g_VideoInitialize.bWii; - case CONFIG_DISABLEFOG: - return g_ActiveConfig.bDisableFog; - case CONFIG_SHOWEFBREGIONS: - return false; - default: - PanicAlert("GetConfig Error: Unknown Config Type!"); - return false; - } -} - -u8 *GetPointer(const u32 &address) -{ - return g_VideoInitialize.pGetMemoryPointer(address); -} - -void SetTextureMode(const BPCmd &bp) -{ - Renderer::SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0); -} - -void SetInterlacingMode(const BPCmd &bp) -{ - // TODO -} - -}; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 227d87c091..5db42fea95 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -49,37 +49,9 @@ #include -int frameCount = 0; static int s_fps = 0; -static bool WindowResized; -static int s_target_width; -static int s_target_height; - -static int s_Fulltarget_width; -static int s_Fulltarget_height; - -static int s_backbuffer_width; -static int s_backbuffer_height; - -static int s_XFB_width; -static int s_XFB_height; - -// ratio of backbuffer size and render area size -static float xScale; -static float yScale; - -// Internal resolution scale (related to xScale/yScale for "Auto" scaling) -static float EFBxScale; -static float EFByScale; - static u32 s_blendMode; -static u32 s_LastEFBScale; -static bool XFBWrited; - -static bool s_bScreenshot = false; -static Common::CriticalSection s_criticalScreenshot; -static char s_sScreenshotName[1024]; ID3D11Buffer* access_efb_cbuf = NULL; ID3D11BlendState* clearblendstates[4] = {NULL}; @@ -250,16 +222,16 @@ void SetupDeviceObjects() D3D::SetDebugObjectName((ID3D11DeviceChild*)access_efb_cbuf, "constant buffer for Renderer::AccessEFB"); D3D11_DEPTH_STENCIL_DESC ddesc; - ddesc.DepthEnable = FALSE; + ddesc.DepthEnable = FALSE; ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - ddesc.StencilEnable = FALSE; + ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + ddesc.StencilEnable = FALSE; ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]); CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen"); ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - ddesc.DepthEnable = TRUE; + ddesc.DepthEnable = TRUE; hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]); CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen"); ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; @@ -299,10 +271,10 @@ void SetupDeviceObjects() hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]); CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen"); - ddesc.DepthEnable = FALSE; - ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - ddesc.DepthFunc = D3D11_COMPARISON_LESS; - ddesc.StencilEnable = FALSE; + ddesc.DepthEnable = FALSE; + ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + ddesc.DepthFunc = D3D11_COMPARISON_LESS; + ddesc.StencilEnable = FALSE; ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; hr = D3D::device->CreateDepthStencilState(&ddesc, &resetdepthstate); @@ -334,9 +306,11 @@ void TeardownDeviceObjects() SAFE_RELEASE(resetraststate); } -bool Renderer::Init() +namespace DX11 +{ + +Renderer::Renderer() { - UpdateActiveConfig(); int x, y, w_temp, h_temp; s_blendMode = 0; @@ -357,26 +331,7 @@ bool Renderer::Init() yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height; s_LastEFBScale = g_ActiveConfig.iEFBScale; - switch(s_LastEFBScale) - { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); - break; - }; - - s_target_width = (int)(EFB_WIDTH * EFBxScale); - s_target_height = (int)(EFB_HEIGHT * EFByScale); - - s_Fulltarget_width = s_target_width; - s_Fulltarget_height = s_target_height; + CalculateTargetSize(); SetupDeviceObjects(); @@ -396,10 +351,9 @@ bool Renderer::Init() D3D::gfxstate->rastdesc.ScissorEnable = TRUE; reset_called = false; - return true; } -void Renderer::Shutdown() +Renderer::~Renderer() { TeardownDeviceObjects(); D3D::EndFrame(); @@ -407,100 +361,6 @@ void Renderer::Shutdown() D3D::Close(); } -int Renderer::GetTargetWidth() { return s_target_width; } -int Renderer::GetTargetHeight() { return s_target_height; } -int Renderer::GetFullTargetWidth() { return s_Fulltarget_width; } -int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; } -float Renderer::GetTargetScaleX() { return EFBxScale; } -float Renderer::GetTargetScaleY() { return EFByScale; } -float Renderer::GetXFBScaleX() { return xScale; } -float Renderer::GetXFBScaleY() { return yScale; } - -// Return the framebuffer size -int Renderer::GetFrameBufferWidth() -{ - return s_backbuffer_width; -} - -int Renderer::GetFrameBufferHeight() -{ - return s_backbuffer_height; -} - -// Create On-Screen-Messages -void Renderer::DrawDebugText() -{ - // OSD menu messages - if (g_ActiveConfig.bOSDHotKey) - { - if (OSDChoice > 0) - { - OSDTime = Common::Timer::GetTimeMs() + 3000; - OSDChoice = -OSDChoice; - } - if ((u32)OSDTime > Common::Timer::GetTimeMs()) - { - std::string T1 = "", T2 = ""; - std::vector T0; - - std::string OSDM1 = StringFromFormat("%i x %i", OSDInternalW, OSDInternalH); - std::string OSDM21; - switch(g_ActiveConfig.iAspectRatio) - { - case ASPECT_AUTO: - OSDM21 = "Auto"; - break; - case ASPECT_FORCE_16_9: - OSDM21 = "16:9"; - break; - case ASPECT_FORCE_4_3: - OSDM21 = "4:3"; - break; - case ASPECT_STRETCH: - OSDM21 = "Stretch"; - break; - } - std::string OSDM22 = - g_ActiveConfig.bCrop ? " (crop)" : ""; - std::string OSDM3 = "Disabled"; - - // If there is more text than this we will have a collision - if (g_ActiveConfig.bShowFPS) - { - T1 += "\n\n"; - T2 += "\n\n"; - } - - // The rows - T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str())); - T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str())); - T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str())); - T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled")); - T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled")); - - // The latest changed setting in yellow - T1 += (OSDChoice == -1) ? T0.at(0) : "\n"; - T1 += (OSDChoice == -2) ? T0.at(1) : "\n"; - T1 += (OSDChoice == -3) ? T0.at(2) : "\n"; - T1 += (OSDChoice == -4) ? T0.at(3) : "\n"; - T1 += (OSDChoice == -5) ? T0.at(4) : "\n"; - - // The other settings in cyan - T2 += (OSDChoice != -1) ? T0.at(0) : "\n"; - T2 += (OSDChoice != -2) ? T0.at(1) : "\n"; - T2 += (OSDChoice != -3) ? T0.at(2) : "\n"; - T2 += (OSDChoice != -4) ? T0.at(3) : "\n"; - T2 += (OSDChoice != -5) ? T0.at(4) : "\n"; - - // Render a shadow, and then the text - Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00); - Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T2.c_str(), 20, 20, 0xFF00FFFF); - } - } -} - void Renderer::RenderText(const char *text, int left, int top, u32 color) { D3D::font.DrawTextScaled((float)left, (float)top, 20.f, 0.0f, color, text); @@ -512,16 +372,15 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) int Ystride = (s_Fulltarget_height - s_target_height) / 2; TargetRectangle result; result.left = (int)(rc.left * EFBxScale) + Xstride; - result.top = (int)(rc.top * EFByScale) + Ystride; + result.top = (int)(rc.top * EFByScale) + Ystride; result.right = (int)(rc.right * EFBxScale) + Xstride; result.bottom = (int)(rc.bottom * EFByScale) + Ystride; return result; } - // With D3D, we have to resize the backbuffer if the window changed // size. -void CheckForResize() +bool Renderer::CheckForResize() { while (EmuWindow::IsSizing()) Sleep(10); @@ -533,7 +392,7 @@ void CheckForResize() GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); int width = rcParentWindow.right - rcParentWindow.left; int height = rcParentWindow.bottom - rcParentWindow.top; - if (width != s_backbuffer_width || height != s_backbuffer_height) + if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); } RECT rcWindow; @@ -542,62 +401,43 @@ void CheckForResize() int client_height = rcWindow.bottom - rcWindow.top; // Sanity check - if ((client_width != s_backbuffer_width || - client_height != s_backbuffer_height) && + if ((client_width != Renderer::GetBackbufferWidth() || + client_height != Renderer::GetBackbufferHeight()) && client_width >= 4 && client_height >= 4) { - WindowResized = true; + return true; } -} -void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) -{ - if (!fbWidth || !fbHeight) - return; - VideoFifo_CheckEFBAccess(); - VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); - XFBWrited = true; - // XXX: Without the VI, how would we know what kind of field this is? So - // just use progressive. - if (g_ActiveConfig.bUseXFB) - { - FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); - } - else - { - Renderer::Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); - } + return false; } bool Renderer::SetScissorRect() { - int xoff = bpmem.scissorOffset.x * 2 - 342; - int yoff = bpmem.scissorOffset.y * 2 - 342; - D3D11_RECT rc = CD3D11_RECT(bpmem.scissorTL.x - xoff - 342, - bpmem.scissorTL.y - yoff - 342, - bpmem.scissorBR.x - xoff - 341, - bpmem.scissorBR.y - yoff - 341); + TargetRectangle rc; + GetScissorRect(rc); int Xstride = (s_Fulltarget_width - s_target_width) / 2; int Ystride = (s_Fulltarget_height - s_target_height) / 2; rc.left = (int)(rc.left * EFBxScale); - rc.top = (int)(rc.top * EFByScale); + rc.top = (int)(rc.top * EFByScale); rc.right = (int)(rc.right * EFBxScale); rc.bottom = (int)(rc.bottom * EFByScale); if (rc.left < 0) rc.left = 0; if (rc.right < 0) rc.right = 0; + if (rc.left > s_target_width) rc.left = s_target_width; if (rc.right > s_target_width) rc.right = s_target_width; + if (rc.top < 0) rc.top = 0; if (rc.bottom < 0) rc.bottom = 0; + if (rc.top > s_target_height) rc.top = s_target_height; if (rc.bottom > s_target_height) rc.bottom = s_target_height; rc.left += Xstride; - rc.top += Ystride; + rc.top += Ystride; rc.right += Xstride; rc.bottom += Ystride; @@ -616,14 +456,14 @@ bool Renderer::SetScissorRect() if (rc.right >= rc.left && rc.bottom >= rc.top) { - D3D::context->RSSetScissorRects(1, &rc); + D3D::context->RSSetScissorRects(1, rc.AsRECT()); return true; } else { //WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom); - rc = CD3D11_RECT(Xstride, Ystride, Xstride + s_target_width, Ystride + s_target_height); - D3D::context->RSSetScissorRects(1, &rc); + *rc.AsRECT() = CD3D11_RECT(Xstride, Ystride, Xstride + s_target_width, Ystride + s_target_height); + D3D::context->RSSetScissorRects(1, rc.AsRECT()); return false; } return false; @@ -758,7 +598,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL); D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f, - - (float)RectToLock.top * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f, + - (float)RectToLock.top * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f, (float)RectToLock.right * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f, - (float)RectToLock.bottom * 2.f / (float)Renderer::GetFullTargetHeight() + 1.f); @@ -768,7 +608,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) } // Called from VertexShaderManager -void UpdateViewport() +void Renderer::UpdateViewport() { // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) // [0] = width/2 @@ -777,20 +617,20 @@ void UpdateViewport() // [3] = xorig + width/2 + 342 // [4] = yorig + height/2 + 342 // [5] = 16777215 * farz - const int old_fulltarget_w = s_Fulltarget_width; - const int old_fulltarget_h = s_Fulltarget_height; + const int old_fulltarget_w = Renderer::GetFullTargetWidth(); + const int old_fulltarget_h = Renderer::GetFullTargetHeight(); int scissorXOff = bpmem.scissorOffset.x * 2; int scissorYOff = bpmem.scissorOffset.y * 2; - int Xstride = (s_Fulltarget_width - s_target_width) / 2; - int Ystride = (s_Fulltarget_height - s_target_height) / 2; + int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2; + int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2; // Stretch picture with increased internal resolution - int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride; - int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * EFByScale) + Ystride; - int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * EFBxScale); - int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * EFByScale); + int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride; + int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride; + int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * Renderer::GetTargetScaleX()); + int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * Renderer::GetTargetScaleY()); if (Width < 0) { X += Width; @@ -822,16 +662,16 @@ void UpdateViewport() if (sizeChanged) { // Make sure that the requested size is actually supported by the GFX driver - if (s_Fulltarget_width > (int)D3D::GetMaxTextureSize() || s_Fulltarget_height > (int)D3D::GetMaxTextureSize()) + if (Renderer::GetFullTargetWidth() > (int)D3D::GetMaxTextureSize() || Renderer::GetFullTargetHeight() > (int)D3D::GetMaxTextureSize()) { // Skip EFB recreation and viewport setting. Most likely causes glitches in this case, but prevents crashes at least - ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D11. Requested EFB size is %dx%d\n", s_Fulltarget_width, s_Fulltarget_height); + ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D11. Requested EFB size is %dx%d\n", Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight()); // Fix the viewport to fit to the old EFB size, TODO: Check this for off-by-one errors - newx *= (float)old_fulltarget_w / (float)s_Fulltarget_width; - newy *= (float)old_fulltarget_h / (float)s_Fulltarget_height; - newwidth *= (float)old_fulltarget_w / (float)s_Fulltarget_width; - newheight *= (float)old_fulltarget_h / (float)s_Fulltarget_height; + newx *= (float)old_fulltarget_w / (float)Renderer::GetFullTargetWidth(); + newy *= (float)old_fulltarget_h / (float)Renderer::GetFullTargetHeight(); + newwidth *= (float)old_fulltarget_w / (float)Renderer::GetFullTargetWidth(); + newheight *= (float)old_fulltarget_h / (float)Renderer::GetFullTargetHeight(); s_Fulltarget_width = old_fulltarget_w; s_Fulltarget_height = old_fulltarget_h; @@ -849,7 +689,7 @@ void UpdateViewport() // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work D3D11_VIEWPORT vp = CD3D11_VIEWPORT(newx, newy, newwidth, newheight, - 0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; + 0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; 1.f); // xfregs.rawViewport[5] / 16777216.0f; D3D::context->RSSetViewports(1, &vp); } @@ -906,6 +746,37 @@ void Renderer::SetBlendMode(bool forceUpdate) } } +bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc) +{ + // copy back buffer to system memory + ID3D11Texture2D* buftex; + D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE); + HRESULT hr = D3D::device->CreateTexture2D(&tex_desc, NULL, &buftex); + if (FAILED(hr)) PanicAlert("Failed to create screenshot buffer texture"); + D3D::context->CopyResource(buftex, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); + + // D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves + D3D11_MAPPED_SUBRESOURCE map; + D3D::context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map); + for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y) + { + u8* ptr = (u8*)map.pData + y * map.RowPitch + 3; + for (unsigned int x = 0; x < D3D::GetBackBufferWidth(); ++x) + { + *ptr = 0xFF; + ptr += 4; + } + } + D3D::context->Unmap(buftex, 0); + + // ready to be saved + hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, filename.c_str()); + buftex->Release(); + + return SUCCEEDED(hr); +} + + // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) { @@ -927,7 +798,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons return; } - Renderer::ResetAPIState(); + ResetAPIState(); // Prepare to copy the XFBs to our backbuffer TargetRectangle dst_rect; @@ -1010,36 +881,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); D3DTexture2D* read_texture = FramebufferManager::GetEFBColorTexture(); - D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); + D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); } // done with drawing the game stuff, good moment to save a screenshot if (s_bScreenshot) { - // copy back buffer to system memory - ID3D11Texture2D* buftex; - D3D11_TEXTURE2D_DESC tex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE); - HRESULT hr = D3D::device->CreateTexture2D(&tex_desc, NULL, &buftex); - if (FAILED(hr)) PanicAlert("Failed to create screenshot buffer texture"); - D3D::context->CopyResource(buftex, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); - - // D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves - D3D11_MAPPED_SUBRESOURCE map; - D3D::context->Map(buftex, 0, D3D11_MAP_READ_WRITE, 0, &map); - for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y) - { - u8* ptr = (u8*)map.pData + y * map.RowPitch + 3; - for (unsigned int x = 0; x < D3D::GetBackBufferWidth(); ++x) - { - *ptr = 0xFF; - ptr += 4; - } - } - D3D::context->Unmap(buftex, 0); - - // ready to be saved - hr = PD3DX11SaveTextureToFileA(D3D::context, buftex, D3DX11_IFF_PNG, s_sScreenshotName); - if (FAILED(hr)) PanicAlert("Failed to save screenshot"); - buftex->Release(); + SaveScreenshot(s_sScreenshotName, dst_rect); s_bScreenshot = false; } @@ -1073,8 +920,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Enable any configuration changes UpdateActiveConfig(); - WindowResized = false; - CheckForResize(); + const bool WindowResized = CheckForResize(); bool xfbchanged = false; @@ -1124,23 +970,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height; s_LastEFBScale = g_ActiveConfig.iEFBScale; - switch(s_LastEFBScale) - { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); - break; - }; - - s_target_width = (int)(EFB_WIDTH * EFBxScale); - s_target_height = (int)(EFB_HEIGHT * EFByScale); + CalculateTargetSize(); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); @@ -1248,13 +1078,13 @@ void Renderer::SetSamplerState(int stage, int texindex) { if (tm0.mag_filter) // linear mag filter { - if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT); + if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_LINEAR); } else // point mag filter { - if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT); + if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT); else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT); else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR); } @@ -1263,13 +1093,13 @@ void Renderer::SetSamplerState(int stage, int texindex) { if (tm0.mag_filter) // linear mag filter { - if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT); + if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT); else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR); } else // point mag filter { - if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_POINT); + if (mip == TEXF_NONE) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_POINT); else if (mip == TEXF_POINT) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_POINT); else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR); } @@ -1288,12 +1118,4 @@ void Renderer::SetInterlacingMode() // TODO } -// Save screenshot -void Renderer::SetScreenshot(const char *filename) -{ - s_criticalScreenshot.Enter(); - strcpy_s(s_sScreenshotName, filename); - s_bScreenshot = true; - s_criticalScreenshot.Leave(); } - diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h new file mode 100644 index 0000000000..bc4d9df3aa --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -0,0 +1,49 @@ + +#ifndef _RENDER_H_ +#define _RENDER_H_ + +#include "RenderBase.h" + +namespace DX11 +{ + +class Renderer : public ::Renderer +{ +public: + Renderer(); + ~Renderer(); + + void SetColorMask(); + void SetBlendMode(bool forceUpdate); + bool SetScissorRect(); + void SetGenerationMode(); + void SetDepthMode(); + void SetLogicOpMode(); + void SetDitherMode(); + void SetLineWidth(); + void SetSamplerState(int stage,int texindex); + void SetInterlacingMode(); + + void RenderText(const char* pstr, int left, int top, u32 color); + + u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); + + void ResetAPIState(); + void RestoreAPIState(); + + TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); + + void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); + + void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); + + void UpdateViewport(); + + bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); + + static bool CheckForResize(); +}; + +} + +#endif diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index e69e6865d4..e3f3b67087 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -117,7 +117,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect, bool bIsIntensityFmt, u32 copyfmt) { - Renderer::ResetAPIState(); + g_renderer->ResetAPIState(); // stretch picture with increased internal resolution const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH); D3D::context->RSSetViewports(1, &vp); @@ -134,7 +134,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB } D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]); - const TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect); + const TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect); // TODO: try targetSource.asRECT(); const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom); @@ -154,7 +154,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture( diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 140a0214e6..6b8086f630 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -194,7 +194,7 @@ void VertexManager::vFlush() { if (usedtextures & (1 << i)) { - Renderer::SetSamplerState(i & 3, i >> 2); + g_renderer->SetSamplerState(i & 3, i >> 2); const FourTexUnits &tex = bpmem.tex[i >> 2]; const TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index ae721c6ce4..739c1ca28e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -41,6 +41,7 @@ #include "XFBConvert.h" #include "Render.h" +#include "MainBase.h" #include "main.h" #include "resource.h" #include "VideoConfigDiag.h" @@ -56,23 +57,6 @@ #include "DLCache.h" HINSTANCE g_hInstance = NULL; -SVideoInitialize g_VideoInitialize; -PLUGIN_GLOBALS* globals = NULL; -static bool s_PluginInitialized = false; - -volatile u32 s_swapRequested = FALSE; -static u32 s_efbAccessRequested = FALSE; -static volatile u32 s_FifoShuttingDown = FALSE; - -static volatile struct -{ - u32 xfbAddr; - FieldType field; - u32 fbWidth; - u32 fbHeight; -} s_beginFieldArgs; - -static volatile EFBAccessType s_AccessEFBType; bool IsD3D() { @@ -231,7 +215,7 @@ void Video_Prepare() s_swapRequested = FALSE; // internal interfaces - Renderer::Init(); + g_renderer = new DX11::Renderer; g_texture_cache = new DX11::TextureCache; g_vertex_manager = new DX11::VertexManager; VertexShaderCache::Init(); @@ -276,7 +260,7 @@ void Shutdown() VertexShaderCache::Shutdown(); delete g_vertex_manager; delete g_texture_cache; - Renderer::Shutdown(); + delete g_renderer; EmuWindow::Close(); s_PluginInitialized = false; @@ -292,187 +276,3 @@ void DoState(unsigned char **ptr, int mode) PointerWrap p(ptr, mode); VideoCommon_DoState(p); } - -void EmuStateChange(PLUGIN_EMUSTATE newState) -{ - Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); -} - -// Enter and exit the video loop -void Video_EnterLoop() -{ - Fifo_EnterLoop(g_VideoInitialize); -} - -void Video_ExitLoop() -{ - Fifo_ExitLoop(); - s_FifoShuttingDown = TRUE; -} - -void Video_SetRendering(bool bEnabled) -{ - Fifo_SetRendering(bEnabled); -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequest() -{ - if(g_ActiveConfig.bUseXFB) - { - if (Common::AtomicLoadAcquire(s_swapRequested)) - { - EFBRectangle rc; - Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); - } - } -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) -{ - if (g_ActiveConfig.bUseXFB) - { - if(Common::AtomicLoadAcquire(s_swapRequested)) - { - 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; - - if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) - VideoFifo_CheckSwapRequest(); - } - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) -{ - if (s_PluginInitialized && g_ActiveConfig.bUseXFB) - { - if (!g_VideoInitialize.bOnThread) - VideoFifo_CheckSwapRequest(); - s_beginFieldArgs.xfbAddr = xfbAddr; - s_beginFieldArgs.field = field; - s_beginFieldArgs.fbWidth = fbWidth; - s_beginFieldArgs.fbHeight = fbHeight; - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_EndField() -{ - if (s_PluginInitialized) - { - Common::AtomicStoreRelease(s_swapRequested, TRUE); - } -} - -void Video_AddMessage(const char* pstr, u32 milliseconds) -{ - OSD::AddMessage(pstr, milliseconds); -} - -// Screenshot -void Video_Screenshot(const char *_szFilename) -{ - Renderer::SetScreenshot(_szFilename); -} - -static struct -{ - EFBAccessType type; - u32 x; - u32 y; - u32 Data; -} s_accessEFBArgs; - -static u32 s_AccessEFBResult = 0; - -void VideoFifo_CheckEFBAccess() -{ - if (Common::AtomicLoadAcquire(s_efbAccessRequested)) - { - s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data); - - Common::AtomicStoreRelease(s_efbAccessRequested, FALSE); - } -} - -u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) -{ - if (s_PluginInitialized) - { - s_accessEFBArgs.type = type; - s_accessEFBArgs.x = x; - s_accessEFBArgs.y = y; - s_accessEFBArgs.Data = InputData; - - Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); - - if (g_VideoInitialize.bOnThread) - { - while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown) - //Common::SleepCurrentThread(1); - Common::YieldCPU(); - } - else - VideoFifo_CheckEFBAccess(); - - return s_AccessEFBResult; - } - - return 0; -} - -void VideoFifo_CheckAsyncRequest() { - VideoFifo_CheckSwapRequest(); - VideoFifo_CheckEFBAccess(); -} - -void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) -{ - CommandProcessor::Read16(_rReturnValue, _Address); -} - -void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address) -{ - CommandProcessor::Write16(_Data, _Address); -} - -void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address) -{ - PixelEngine::Read16(_rReturnValue, _Address); -} - -void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address) -{ - PixelEngine::Write16(_Data, _Address); -} - -void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address) -{ - PixelEngine::Write32(_Data, _Address); -} - -void Video_GatherPipeBursted(void) -{ - CommandProcessor::GatherPipeBursted(); -} - -void Video_WaitForFrameFinish(void) -{ - CommandProcessor::WaitForFrameFinish(); -} - -bool Video_IsFifoBusy(void) -{ - return CommandProcessor::isFifoBusy; -} - -void Video_AbortFrame(void) -{ - CommandProcessor::AbortFrame(); -} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.h b/Source/Plugins/Plugin_VideoDX11/Src/main.h index 05ea0677fd..1a0ee15e9b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.h @@ -20,10 +20,8 @@ #include "PluginSpecs_Video.h" #include "Render.h" +#include "MainBase.h" extern SVideoInitialize g_VideoInitialize; -extern volatile u32 s_swapRequested; -void VideoFifo_CheckEFBAccess(); -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj index 57a420f9d9..625923e374 100644 --- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj +++ b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj @@ -675,14 +675,6 @@ > - - - - @@ -710,6 +702,10 @@ RelativePath=".\Src\Render.cpp" > + + diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp index 6bf677fdfe..f3c9ab144b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp @@ -192,7 +192,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c return; } - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); + TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index bab80162e4..1a113f3ddc 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -54,27 +54,6 @@ static int s_fps = 0; -static bool WindowResized; -static int s_target_width; -static int s_target_height; - -static int s_Fulltarget_width; -static int s_Fulltarget_height; - -static int s_backbuffer_width; -static int s_backbuffer_height; - -static int s_XFB_width; -static int s_XFB_height; - -// ratio of backbuffer size and render area size -static float xScale; -static float yScale; - -// Internal resolution scale (related to xScale/yScale for "Auto" scaling) -static float EFBxScale; -static float EFByScale; - static int s_recordWidth; static int s_recordHeight; @@ -83,18 +62,10 @@ static bool s_bAVIDumping; static u32 s_blendMode; static u32 s_LastAA; -static u32 s_LastEFBScale; static bool IS_AMD; -static bool XFBWrited = false; - -// used extern by other files. need to clean this up at some point. -int frameCount; static char *st; -static bool s_bScreenshot = false; -static Common::CriticalSection s_criticalScreenshot; -static char s_sScreenshotName[1024]; static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL; @@ -273,11 +244,14 @@ void TeardownDeviceObjects() TextureConverter::Shutdown(); } +namespace DX9 +{ + // Init functions -bool Renderer::Init() +Renderer::Renderer() { st = new char[32768]; - UpdateActiveConfig(); + int fullScreenRes, x, y, w_temp, h_temp; s_blendMode = 0; // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead @@ -321,32 +295,10 @@ bool Renderer::Init() } s_LastAA = g_ActiveConfig.iMultisampleMode; - s_LastEFBScale = g_ActiveConfig.iEFBScale; float SupersampleCoeficient = s_LastAA + 1; - switch(s_LastEFBScale) - { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = g_ActiveConfig.iEFBScale - 1; - EFByScale = EFBxScale; - break; - }; - - EFBxScale *= SupersampleCoeficient; - EFByScale *= SupersampleCoeficient; - s_target_width = EFB_WIDTH * EFBxScale; - s_target_height = EFB_HEIGHT * EFByScale; - - s_Fulltarget_width = s_target_width; - s_Fulltarget_height = s_target_height; + s_LastEFBScale = g_ActiveConfig.iEFBScale; + CalculateTargetSize(SupersampleCoeficient); s_bLastFrameDumped = false; s_bAVIDumping = false; @@ -384,10 +336,9 @@ bool Renderer::Init() D3D::BeginFrame(); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - return true; } -void Renderer::Shutdown() +Renderer::~Renderer() { TeardownDeviceObjects(); D3D::EndFrame(); @@ -398,142 +349,7 @@ void Renderer::Shutdown() { AVIDump::Stop(); } - delete [] st; -} - -// Return the rendering target width and height -int Renderer::GetTargetWidth() -{ - return s_target_width; -} - -int Renderer::GetTargetHeight() -{ - return s_target_height; -} - -int Renderer::GetFullTargetWidth() -{ - return s_Fulltarget_width; -} - -int Renderer::GetFullTargetHeight() -{ - return s_Fulltarget_height; -} - -float Renderer::GetTargetScaleX() -{ - return EFBxScale; -} - -float Renderer::GetTargetScaleY() -{ - return EFByScale; -} - -float Renderer::GetXFBScaleX() -{ - return xScale; -} - -float Renderer::GetXFBScaleY() -{ - return yScale; -} - -// Create On-Screen-Messages -void Renderer::DrawDebugText() -{ - // OSD Menu messages - if (g_ActiveConfig.bOSDHotKey) - { - if (OSDChoice > 0) - { - OSDTime = Common::Timer::GetTimeMs() + 3000; - OSDChoice = -OSDChoice; - } - if ((u32)OSDTime > Common::Timer::GetTimeMs()) - { - std::string T1 = "", T2 = ""; - std::vector T0; - - std::string OSDM1; - switch(g_ActiveConfig.iEFBScale) - { - case 0: - OSDM1 = "Auto (fractional)"; - break; - case 1: - OSDM1 = "Auto (integral)"; - break; - case 2: - OSDM1 = "Native"; - break; - case 3: - OSDM1 = "2x"; - break; - case 4: - OSDM1 = "3x"; - break; - } - - std::string OSDM21; - switch(g_ActiveConfig.iAspectRatio) - { - case ASPECT_AUTO: - OSDM21 = "Auto"; - break; - case ASPECT_FORCE_16_9: - OSDM21 = "16:9"; - break; - case ASPECT_FORCE_4_3: - OSDM21 = "4:3"; - break; - case ASPECT_STRETCH: - OSDM21 = "Stretch"; - break; - } - std::string OSDM22 = - g_ActiveConfig.bCrop ? " (crop)" : ""; - std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" : - g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM"; - - // If there is more text than this we will have a collision - if (g_ActiveConfig.bShowFPS) - { - T1 += "\n\n"; - T2 += "\n\n"; - } - - // The rows - T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str())); - T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str())); - T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str())); - T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled")); - T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled")); - - // The latest changed setting in yellow - T1 += (OSDChoice == -1) ? T0.at(0) : "\n"; - T1 += (OSDChoice == -2) ? T0.at(1) : "\n"; - T1 += (OSDChoice == -3) ? T0.at(2) : "\n"; - T1 += (OSDChoice == -4) ? T0.at(3) : "\n"; - T1 += (OSDChoice == -5) ? T0.at(4) : "\n"; - - // The other settings in cyan - T2 += (OSDChoice != -1) ? T0.at(0) : "\n"; - T2 += (OSDChoice != -2) ? T0.at(1) : "\n"; - T2 += (OSDChoice != -3) ? T0.at(2) : "\n"; - T2 += (OSDChoice != -4) ? T0.at(3) : "\n"; - T2 += (OSDChoice != -5) ? T0.at(4) : "\n"; - - // Render a shadow, and then the text - Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00); - Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T2.c_str(), 20, 20, 0xFF00FFFF); - } - } + delete[] st; } void Renderer::RenderText(const char *text, int left, int top, u32 color) @@ -553,6 +369,8 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) return result; } +} + void formatBufferDump(const char *in, char *out, int w, int h, int p) { for (int y = 0; y < h; y++) @@ -567,9 +385,12 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p) } } +namespace DX9 +{ + // With D3D, we have to resize the backbuffer if the window changed // size. -void CheckForResize() +bool Renderer::CheckForResize() { while (EmuWindow::IsSizing()) Sleep(10); @@ -581,17 +402,18 @@ void CheckForResize() GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); int width = rcParentWindow.right - rcParentWindow.left; int height = rcParentWindow.bottom - rcParentWindow.top; - if (width != s_backbuffer_width || height != s_backbuffer_height) + if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); } + RECT rcWindow; GetClientRect(EmuWindow::GetWnd(), &rcWindow); int client_width = rcWindow.right - rcWindow.left; int client_height = rcWindow.bottom - rcWindow.top; // Sanity check - if ((client_width != s_backbuffer_width || - client_height != s_backbuffer_height) && + if ((client_width != Renderer::GetBackbufferWidth() || + client_height != Renderer::GetBackbufferHeight()) && client_width >= 4 && client_height >= 4) { TeardownDeviceObjects(); @@ -601,47 +423,29 @@ void CheckForResize() s_backbuffer_height = D3D::GetBackBufferHeight(); if(ScreenShootMEMSurface) ScreenShootMEMSurface->Release(); - D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - WindowResized = true; - } -} + D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), + D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); -void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) -{ - if (!fbWidth || !fbHeight) - return; - VideoFifo_CheckEFBAccess(); - VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); - XFBWrited = true; - // XXX: Without the VI, how would we know what kind of field this is? So - // just use progressive. - if (g_ActiveConfig.bUseXFB) - { - FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); - } - else - { - Renderer::Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); + return true; } + + return false; } bool Renderer::SetScissorRect() { - int xoff = bpmem.scissorOffset.x * 2 - 342; - int yoff = bpmem.scissorOffset.y * 2 - 342; - RECT rc; - rc.left = (int)((float)bpmem.scissorTL.x - xoff - 342); - rc.top = (int)((float)bpmem.scissorTL.y - yoff - 342); - rc.right = (int)((float)bpmem.scissorBR.x - xoff - 341); - rc.bottom = (int)((float)bpmem.scissorBR.y - yoff - 341); + TargetRectangle rc; + GetScissorRect(rc); if (rc.left < 0) rc.left = 0; if (rc.right < 0) rc.right = 0; + if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH; if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH; + if (rc.top < 0) rc.top = 0; if (rc.bottom < 0) rc.bottom = 0; + if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT; if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT; @@ -669,7 +473,7 @@ bool Renderer::SetScissorRect() // Check that the coordinates are good if (rc.right != rc.left && rc.bottom != rc.top) { - D3D::dev->SetScissorRect(&rc); + D3D::dev->SetScissorRect(rc.AsRECT()); return true; } else @@ -679,7 +483,7 @@ bool Renderer::SetScissorRect() rc.top = Ystride; rc.right = Xstride + s_target_width; rc.bottom = Ystride + s_target_height; - D3D::dev->SetScissorRect(&rc); + D3D::dev->SetScissorRect(rc.AsRECT()); } return false; } @@ -890,7 +694,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) } // Called from VertexShaderManager -void UpdateViewport() +void Renderer::UpdateViewport() { // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) // [0] = width/2 @@ -899,22 +703,20 @@ void UpdateViewport() // [3] = xorig + width/2 + 342 // [4] = yorig + height/2 + 342 // [5] = 16777215 * farz - const int old_fulltarget_w = s_Fulltarget_width; - const int old_fulltarget_h = s_Fulltarget_height; + const int old_fulltarget_w = Renderer::GetFullTargetWidth(); + const int old_fulltarget_h = Renderer::GetFullTargetHeight(); int scissorXOff = bpmem.scissorOffset.x * 2; int scissorYOff = bpmem.scissorOffset.y * 2; - int Xstride = (s_Fulltarget_width - s_target_width) / 2; - int Ystride = (s_Fulltarget_height - s_target_height) / 2; - - D3DVIEWPORT9 vp; + int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2; + int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2; // Stretch picture with increased internal resolution - int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride; - int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * EFByScale) + Ystride; - int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale); - int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale); + int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride; + int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride; + int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX()); + int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY()); if (Width < 0) { X += Width; @@ -940,14 +742,14 @@ void UpdateViewport() } if (!IS_AMD) { - if(X + Width > s_Fulltarget_width) + if(X + Width > Renderer::GetFullTargetWidth()) { - s_Fulltarget_width += (X + Width - s_Fulltarget_width) * 2; + s_Fulltarget_width += (X + Width - Renderer::GetFullTargetWidth()) * 2; sizeChanged = true; } - if(Y + Height > s_Fulltarget_height) + if(Y + Height > Renderer::GetFullTargetHeight()) { - s_Fulltarget_height += (Y + Height - s_Fulltarget_height) * 2; + s_Fulltarget_height += (Y + Height - Renderer::GetFullTargetHeight()) * 2; sizeChanged = true; } } @@ -955,16 +757,16 @@ void UpdateViewport() { D3DCAPS9 caps = D3D::GetCaps(); // Make sure that the requested size is actually supported by the GFX driver - if (s_Fulltarget_width > caps.MaxTextureWidth || s_Fulltarget_height > caps.MaxTextureHeight) + if (Renderer::GetFullTargetWidth() > caps.MaxTextureWidth || Renderer::GetFullTargetHeight() > caps.MaxTextureHeight) { // Skip EFB recreation and viewport setting. Most likely causes glitches in this case, but prevents crashes at least - ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D9. Requested EFB size is %dx%d, keeping the %dx%d EFB now\n", s_Fulltarget_width, s_Fulltarget_height, old_fulltarget_w, old_fulltarget_h); + ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D9. Requested EFB size is %dx%d, keeping the %dx%d EFB now\n", Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), old_fulltarget_w, old_fulltarget_h); // Fix the viewport to fit to the old EFB size, TODO: Check this for off-by-one errors - X *= old_fulltarget_w / s_Fulltarget_width; - Y *= old_fulltarget_h / s_Fulltarget_height; - Width *= old_fulltarget_w / s_Fulltarget_width; - Height *= old_fulltarget_h / s_Fulltarget_height; + X *= old_fulltarget_w / Renderer::GetFullTargetWidth(); + Y *= old_fulltarget_h / Renderer::GetFullTargetHeight(); + Width *= old_fulltarget_w / Renderer::GetFullTargetWidth(); + Height *= old_fulltarget_h / Renderer::GetFullTargetHeight(); s_Fulltarget_width = old_fulltarget_w; s_Fulltarget_height = old_fulltarget_h; @@ -981,6 +783,8 @@ void UpdateViewport() D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); } } + + D3DVIEWPORT9 vp; vp.X = X; vp.Y = Y; vp.Width = Width; @@ -1040,6 +844,24 @@ void Renderer::SetBlendMode(bool forceUpdate) } } +bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &dst_rect) +{ + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if(FAILED(hr)) + { + PanicAlert("Error dumping surface data."); + return false; + } + hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); + if(FAILED(hr)) + { + PanicAlert("Error saving screen."); + return false; + } + + return true; +} + // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) { @@ -1054,7 +876,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; u32 xfbCount = 0; - const XFBSourceBase *const *xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { g_VideoInitialize.pCopiedToXFB(false); @@ -1062,6 +884,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } ResetAPIState(); + if(g_ActiveConfig.bAnaglyphStereo) { static bool RightFrame = false; @@ -1113,7 +936,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons int Width = dst_rect.right - dst_rect.left; int Height = dst_rect.bottom - dst_rect.top; - // Sanity check + // Sanity check if (X < 0) X = 0; if (Y < 0) Y = 0; if (X > s_backbuffer_width) X = s_backbuffer_width; @@ -1213,16 +1036,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (s_bScreenshot) { s_criticalScreenshot.Enter(); - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if(FAILED(hr)) - { - PanicAlert("Error dumping surface data."); - } - hr = PD3DXSaveSurfaceToFileA(s_sScreenshotName, D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); - if(FAILED(hr)) - { - PanicAlert("Error saving screen."); - } + SaveScreenshot(s_sScreenshotName, dst_rect); s_bScreenshot = false; s_criticalScreenshot.Leave(); } @@ -1298,8 +1112,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Enable any configuration changes UpdateActiveConfig(); - WindowResized = false; - CheckForResize(); + const bool WindowResized = CheckForResize(); bool xfbchanged = false; @@ -1343,31 +1156,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } float SupersampleCoeficient = s_LastAA + 1; + s_LastEFBScale = g_ActiveConfig.iEFBScale; - switch(s_LastEFBScale) - { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = g_ActiveConfig.iEFBScale - 1; - EFByScale = EFBxScale; - break; - }; - - EFBxScale *= SupersampleCoeficient; - EFByScale *= SupersampleCoeficient; - - s_target_width = EFB_WIDTH * EFBxScale; - s_target_height = EFB_HEIGHT * EFByScale; - - s_Fulltarget_width = s_target_width; - s_Fulltarget_height = s_target_height; + CalculateTargetSize(SupersampleCoeficient); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); @@ -1416,7 +1207,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // For testing zbuffer targets. // Renderer::SetZBufferRender(); // SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, - // GetTargetWidth(), GetTargetHeight()); + // GetTargetWidth(), GetTargetHeight()); g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB); XFBWrited = false; } @@ -1539,11 +1330,4 @@ void Renderer::SetInterlacingMode() // TODO } -// Save screenshot -void Renderer::SetScreenshot(const char *filename) -{ - s_criticalScreenshot.Enter(); - strcpy_s(s_sScreenshotName, filename); - s_bScreenshot = true; - s_criticalScreenshot.Leave(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h new file mode 100644 index 0000000000..dc8e30fed1 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h @@ -0,0 +1,49 @@ + +#ifndef _RENDER_H_ +#define _RENDER_H_ + +#include "RenderBase.h" + +namespace DX9 +{ + +class Renderer : public ::Renderer +{ +public: + Renderer(); + ~Renderer(); + + void SetColorMask(); + void SetBlendMode(bool forceUpdate); + bool SetScissorRect(); + void SetGenerationMode(); + void SetDepthMode(); + void SetLogicOpMode(); + void SetDitherMode(); + void SetLineWidth(); + void SetSamplerState(int stage,int texindex); + void SetInterlacingMode(); + + void RenderText(const char* pstr, int left, int top, u32 color); + + u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); + + void ResetAPIState(); + void RestoreAPIState(); + + TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); + + void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); + + void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); + + void UpdateViewport(); + + bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); + + static bool CheckForResize(); +}; + +} + +#endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 7fecb82704..5c009a2d8c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -102,7 +102,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation - TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect); + TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect); RECT sourcerect; sourcerect.bottom = targetSource.bottom; sourcerect.left = targetSource.left; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index d47ea677b3..106a56a9dd 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -372,11 +372,11 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf cacheBytes = 64; int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); - Renderer::ResetAPIState(); + g_renderer->ResetAPIState(); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) @@ -459,11 +459,11 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc 1.0f, (float)Renderer::GetFullTargetWidth(), (float)Renderer::GetFullTargetHeight()); - Renderer::ResetAPIState(); + g_renderer->ResetAPIState(); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); } @@ -479,7 +479,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE int srcFmtWidth = srcWidth / 2; - Renderer::ResetAPIState(); // reset any game specific settings + g_renderer->ResetAPIState(); // reset any game specific settings LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false); LPDIRECT3DSURFACE9 Rendersurf = NULL; destTexture->GetSurfaceLevel(0,&Rendersurf); @@ -536,7 +536,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE D3D::SetTexture(0,NULL); D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); Rendersurf->Release(); s_srcTexture->Release(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index a134e55c41..949efddb1f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -131,7 +131,7 @@ void VertexManager::vFlush() { if (usedtextures & (1 << i)) { - Renderer::SetSamplerState(i & 3, i >> 2); + g_renderer->SetSamplerState(i & 3, i >> 2); FourTexUnits &tex = bpmem.tex[i >> 2]; TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 7c60540832..9a81c72ddf 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -29,6 +29,7 @@ #include "Debugger/Debugger.h" #endif // HAVE_WX +#include "MainBase.h" #include "main.h" #include "VideoConfig.h" #include "Fifo.h" @@ -36,6 +37,7 @@ #include "TextureCache.h" #include "BPStructs.h" #include "VertexManager.h" +#include "FramebufferManager.h" #include "VertexLoaderManager.h" #include "VertexShaderManager.h" #include "PixelShaderManager.h" @@ -53,23 +55,6 @@ #include "DLCache.h" HINSTANCE g_hInstance = NULL; -SVideoInitialize g_VideoInitialize; -PLUGIN_GLOBALS* globals = NULL; -static bool s_PluginInitialized = false; - -volatile u32 s_swapRequested = FALSE; -static u32 s_efbAccessRequested = FALSE; -static volatile u32 s_FifoShuttingDown = FALSE; - -static volatile struct -{ - u32 xfbAddr; - FieldType field; - u32 fbWidth; - u32 fbHeight; -} s_beginFieldArgs; - -static volatile EFBAccessType s_AccessEFBType; bool IsD3D() { @@ -251,7 +236,7 @@ void Video_Prepare() s_swapRequested = FALSE; // internal interfaces - Renderer::Init(); + g_renderer = new DX9::Renderer; g_texture_cache = new DX9::TextureCache; g_vertex_manager = new DX9::VertexManager; // VideoCommon @@ -291,7 +276,7 @@ void Shutdown() VertexShaderCache::Shutdown(); delete g_vertex_manager; delete g_texture_cache; - Renderer::Shutdown(); + delete g_renderer; D3D::Shutdown(); EmuWindow::Close(); } @@ -306,192 +291,3 @@ void DoState(unsigned char **ptr, int mode) PointerWrap p(ptr, mode); VideoCommon_DoState(p); } - -void EmuStateChange(PLUGIN_EMUSTATE newState) -{ - Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); -} - -// Enter and exit the video loop -void Video_EnterLoop() -{ - Fifo_EnterLoop(g_VideoInitialize); -} - -void Video_ExitLoop() -{ - Fifo_ExitLoop(); - s_FifoShuttingDown = TRUE; -} - -void Video_SetRendering(bool bEnabled) -{ - Fifo_SetRendering(bEnabled); -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequest() -{ - if(g_ActiveConfig.bUseXFB) - { - if (Common::AtomicLoadAcquire(s_swapRequested)) - { - EFBRectangle rc; - Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); - } - } -} - -static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) -{ - return !((aLower >= bUpper) || (bLower >= aUpper)); -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) -{ - if (g_ActiveConfig.bUseXFB) - { - if(Common::AtomicLoadAcquire(s_swapRequested)) - { - 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; - - if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) - VideoFifo_CheckSwapRequest(); - } - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) -{ - if (s_PluginInitialized && g_ActiveConfig.bUseXFB) - { - if (!g_VideoInitialize.bOnThread) - VideoFifo_CheckSwapRequest(); - s_beginFieldArgs.xfbAddr = xfbAddr; - s_beginFieldArgs.field = field; - s_beginFieldArgs.fbWidth = fbWidth; - s_beginFieldArgs.fbHeight = fbHeight; - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_EndField() -{ - if (s_PluginInitialized) - { - Common::AtomicStoreRelease(s_swapRequested, TRUE); - } -} - -void Video_AddMessage(const char* pstr, u32 milliseconds) -{ - OSD::AddMessage(pstr, milliseconds); -} - -// Screenshot -void Video_Screenshot(const char *_szFilename) -{ - Renderer::SetScreenshot(_szFilename); -} - -static struct -{ - EFBAccessType type; - u32 x; - u32 y; - u32 Data; -} s_accessEFBArgs; - -static u32 s_AccessEFBResult = 0; - -void VideoFifo_CheckEFBAccess() -{ - if (Common::AtomicLoadAcquire(s_efbAccessRequested)) - { - s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data); - - Common::AtomicStoreRelease(s_efbAccessRequested, FALSE); - } -} - -u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) -{ - if (s_PluginInitialized) - { - s_accessEFBArgs.type = type; - s_accessEFBArgs.x = x; - s_accessEFBArgs.y = y; - s_accessEFBArgs.Data = InputData; - - Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); - - if (g_VideoInitialize.bOnThread) - { - while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown) - //Common::SleepCurrentThread(1); - Common::YieldCPU(); - } - else - VideoFifo_CheckEFBAccess(); - - return s_AccessEFBResult; - } - - return 0; -} - -void VideoFifo_CheckAsyncRequest() { - VideoFifo_CheckSwapRequest(); - VideoFifo_CheckEFBAccess(); -} - -void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) -{ - CommandProcessor::Read16(_rReturnValue, _Address); -} - -void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address) -{ - CommandProcessor::Write16(_Data, _Address); -} - -void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address) -{ - PixelEngine::Read16(_rReturnValue, _Address); -} - -void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address) -{ - PixelEngine::Write16(_Data, _Address); -} - -void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address) -{ - PixelEngine::Write32(_Data, _Address); -} - -void Video_GatherPipeBursted(void) -{ - CommandProcessor::GatherPipeBursted(); -} - -void Video_WaitForFrameFinish(void) -{ - CommandProcessor::WaitForFrameFinish(); -} - -bool Video_IsFifoBusy(void) -{ - return CommandProcessor::isFifoBusy; -} - -void Video_AbortFrame(void) -{ - CommandProcessor::AbortFrame(); -} diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.h b/Source/Plugins/Plugin_VideoDX9/Src/main.h index 05ea0677fd..1a0ee15e9b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.h @@ -20,10 +20,8 @@ #include "PluginSpecs_Video.h" #include "Render.h" +#include "MainBase.h" extern SVideoInitialize g_VideoInitialize; -extern volatile u32 s_swapRequested; -void VideoFifo_CheckEFBAccess(); -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj index 9473bc8e3e..1480b4f1d1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcproj @@ -733,10 +733,6 @@ - - @@ -765,6 +761,10 @@ RelativePath=".\Src\Render.cpp" > + + diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp deleted file mode 100644 index 1d27a1b600..0000000000 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "BPFunctions.h" -#include "Globals.h" -#include "Profiler.h" -#include "VideoConfig.h" -#include "VertexManager.h" -#include "Render.h" -#include "TextureCache.h" -#include "TextureConverter.h" -#include "VertexShaderManager.h" -#include "main.h" - -namespace BPFunctions -{ -// ---------------------------------------------- -// State translation lookup tables -// Reference: Yet Another Gamecube Documentation -// ---------------------------------------------- - - -void FlushPipeline() -{ - VertexManager::Flush(); -} - -void SetGenerationMode(const BPCmd &bp) -{ - Renderer::SetGenerationMode(); -} - -void SetScissor(const BPCmd &bp) -{ - Renderer::SetScissorRect(); -} - -void SetLineWidth(const BPCmd &bp) -{ - Renderer::SetLineWidth(); -} - -void SetDepthMode(const BPCmd &bp) -{ - Renderer::SetDepthMode(); -} - -void SetBlendMode(const BPCmd &bp) -{ - Renderer::SetBlendMode(false); -} -void SetDitherMode(const BPCmd &bp) -{ - Renderer::SetDitherMode(); -} -void SetLogicOpMode(const BPCmd &bp) -{ - Renderer::SetLogicOpMode(); -} - -void SetColorMask(const BPCmd &bp) -{ - Renderer::SetColorMask(); -} - -void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf) -{ - // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) - if (!g_ActiveConfig.bEFBCopyDisable) - { - TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, !!scaleByHalf, rc); - } -} - -void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) -{ - bool colorEnable = bpmem.blendmode.colorupdate; - bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate); - bool zEnable = bpmem.zmode.updateenable; - - if (colorEnable || alphaEnable || zEnable) - { - u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; - u32 z = bpmem.clearZValue; - - Renderer::ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z); - } -} - -void RestoreRenderState(const BPCmd &bp) -{ - Renderer::RestoreAPIState(); -} - -bool GetConfig(const int &type) -{ - switch (type) - { - case CONFIG_ISWII: - return g_VideoInitialize.bWii; - case CONFIG_DISABLEFOG: - return g_ActiveConfig.bDisableFog; - case CONFIG_SHOWEFBREGIONS: - return g_ActiveConfig.bShowEFBCopyRegions; - default: - PanicAlert("GetConfig Error: Unknown Config Type!"); - return false; - } -} - -u8 *GetPointer(const u32 &address) -{ - return g_VideoInitialize.pGetMemoryPointer(address); -} - -void SetTextureMode(const BPCmd &bp) -{ - // TODO -} - -void SetInterlacingMode(const BPCmd &bp) -{ - // TODO -} - -}; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index 758759c8c6..30b6d43916 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -211,7 +211,7 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is // required. - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); + TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); // Resolve. @@ -241,7 +241,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is // required. - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); + TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); // Resolve. @@ -269,7 +269,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c return; } - TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc); + TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc); TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index ba1fcd7298..4a8c158d27 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -82,7 +82,6 @@ CGprofile g_cgfProf; RasterFont* s_pfont = NULL; -static bool s_bLastFrameDumped = false; #if defined _WIN32 || defined HAVE_AVCODEC static bool s_bAVIDumping = false; #else @@ -96,40 +95,10 @@ static int s_MSAACoverageSamples = 0; bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp static bool s_bHaveCoverageMSAA = false; static u32 s_blendMode; -static int s_LastEFBScale; -static volatile bool s_bScreenshot = false; #if defined(HAVE_WX) && HAVE_WX static Common::Thread *scrshotThread = 0; #endif -static Common::CriticalSection s_criticalScreenshot; -static std::string s_sScreenshotName; - -int frameCount; - -// The custom resolution -static int s_Fulltarget_width; -static int s_Fulltarget_height; - -// TODO: Add functionality to reinit all the render targets when the window is resized. -static int s_backbuffer_width; -static int s_backbuffer_height; -// The framebuffer size -static int s_target_width; -static int s_target_height; - -static unsigned int s_XFB_width; -static unsigned int s_XFB_height; - -static float xScale; -static float yScale; - -static float EFBxScale; -static float EFByScale; - -static bool s_skipSwap = false; - -static bool XFBWrited = false; int OSDChoice = 0 , OSDTime = 0, OSDInternalW = 0, OSDInternalH = 0; @@ -215,10 +184,12 @@ void VideoConfig::UpdateProjectionHack() ::UpdateProjectionHack(g_Config.iPhackvalue); } -// Init functions -bool Renderer::Init() +namespace OGL +{ + +// Init functions +Renderer::Renderer() { - UpdateActiveConfig(); bool bSuccess = true; s_blendMode = 0; s_MSAACoverageSamples = 0; @@ -226,20 +197,37 @@ bool Renderer::Init() switch (g_ActiveConfig.iMultisampleMode) { - case MULTISAMPLE_OFF: s_MSAASamples = 1; break; - case MULTISAMPLE_2X: s_MSAASamples = 2; break; - case MULTISAMPLE_4X: s_MSAASamples = 4; break; - case MULTISAMPLE_8X: s_MSAASamples = 8; break; + case MULTISAMPLE_OFF: + s_MSAASamples = 1; + break; + case MULTISAMPLE_2X: + s_MSAASamples = 2; + break; + case MULTISAMPLE_4X: + s_MSAASamples = 4; + break; + case MULTISAMPLE_8X: + s_MSAASamples = 8; + break; case MULTISAMPLE_CSAA_8X: - s_MSAASamples = 4; s_MSAACoverageSamples = 8; break; + s_MSAASamples = 4; + s_MSAACoverageSamples = 8; + break; case MULTISAMPLE_CSAA_8XQ: - s_MSAASamples = 8; s_MSAACoverageSamples = 8; break; + s_MSAASamples = 8; + s_MSAACoverageSamples = 8; + break; case MULTISAMPLE_CSAA_16X: - s_MSAASamples = 4; s_MSAACoverageSamples = 16; break; + s_MSAASamples = 4; + s_MSAACoverageSamples = 16; + break; case MULTISAMPLE_CSAA_16XQ: - s_MSAASamples = 8; s_MSAACoverageSamples = 16; break; + s_MSAASamples = 8; + s_MSAACoverageSamples = 16; + break; default: - s_MSAASamples = 1; + s_MSAASamples = 1; + break; } #if defined HAVE_CG && HAVE_CG @@ -255,7 +243,7 @@ bool Renderer::Init() PanicAlert("Your OpenGL Driver seems to be not working.\n" "Please make sure your drivers are up-to-date and\n" "that your video hardware is OpenGL 2.x compatible."); - return false; + return; // TODO: fail } INFO_LOG(VIDEO, "Supported OpenGL Extensions:"); @@ -280,7 +268,7 @@ bool Renderer::Init() if (glewInit() != GLEW_OK) { ERROR_LOG(VIDEO, "glewInit() failed! Does your video card support OpenGL 2.x?"); - return false; + return; // TODO: fail } if (!GLEW_EXT_framebuffer_object) @@ -311,7 +299,7 @@ bool Renderer::Init() } if (!bSuccess) - return false; + return; // TODO: fail // Decide frambuffer size s_backbuffer_width = (int)OpenGL_GetBackbufferWidth(); @@ -366,27 +354,7 @@ bool Renderer::Init() } s_LastEFBScale = g_ActiveConfig.iEFBScale; - switch(s_LastEFBScale) - { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = (float)(g_ActiveConfig.iEFBScale - 1); - EFByScale = EFBxScale; - break; - }; - - s_target_width = EFB_WIDTH * EFBxScale; - s_target_height = EFB_HEIGHT * EFByScale; - - s_Fulltarget_width = s_target_width; - s_Fulltarget_height = s_target_height; + CalculateTargetSize(); // Because of the fixed framebuffer size we need to disable the resolution // options while running @@ -411,13 +379,13 @@ bool Renderer::Init() if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) { ERROR_LOG(VIDEO, "arbvp1 not supported"); - return false; + return; // TODO: fail } if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE) { ERROR_LOG(VIDEO, "arbfp1 not supported"); - return false; + return; // TODO: fail } g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX); @@ -505,10 +473,12 @@ bool Renderer::Init() glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); UpdateActiveConfig(); - return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess; + + //return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess; + return; } -void Renderer::Shutdown() +Renderer::~Renderer() { g_Config.bRunning = false; UpdateActiveConfig(); @@ -539,49 +509,8 @@ void Renderer::Shutdown() #endif } -// Return the rendering target width and height -int Renderer::GetTargetWidth() -{ - return s_target_width; -} - -int Renderer::GetTargetHeight() -{ - return s_target_height; -} - -int Renderer::GetFullTargetWidth() -{ - return s_Fulltarget_width; -} - -int Renderer::GetFullTargetHeight() -{ - return s_Fulltarget_height; -} - -float Renderer::GetTargetScaleX() -{ - return EFBxScale; -} - -float Renderer::GetTargetScaleY() -{ - return EFByScale; -} - -float Renderer::GetXFBScaleX() -{ - return xScale; -} - -float Renderer::GetXFBScaleY() -{ - return yScale; -} - // Create On-Screen-Messages -void Renderer::DrawDebugText() +void Renderer::DrawDebugInfo() { // Reset viewport for drawing text glViewport(0, 0, OpenGL_GetBackbufferWidth(), OpenGL_GetBackbufferHeight()); @@ -651,108 +580,21 @@ void Renderer::DrawDebugText() Renderer::RenderText(debugtext_buffer, 21, 21, 0xDD000000); Renderer::RenderText(debugtext_buffer, 20, 20, 0xFF00FFFF); } - - // OSD Menu messages - if (g_ActiveConfig.bOSDHotKey) - { - if (OSDChoice > 0) - { - OSDTime = Common::Timer::GetTimeMs() + 3000; - OSDChoice = -OSDChoice; - } - if ((u32)OSDTime > Common::Timer::GetTimeMs()) - { - std::string T1 = "", T2 = ""; - std::vector T0; - - std::string OSDM1; - switch(g_ActiveConfig.iEFBScale) - { - case 0: - OSDM1 = "Auto (fractional)"; - break; - case 1: - OSDM1 = "Auto (integral)"; - break; - case 2: - OSDM1 = "Native"; - break; - case 3: - OSDM1 = "2x"; - break; - case 4: - OSDM1 = "3x"; - break; - } - - std::string OSDM21; - switch(g_ActiveConfig.iAspectRatio) - { - case ASPECT_AUTO: - OSDM21 = "Auto"; - break; - case ASPECT_FORCE_16_9: - OSDM21 = "16:9"; - break; - case ASPECT_FORCE_4_3: - OSDM21 = "4:3"; - break; - case ASPECT_STRETCH: - OSDM21 = "Stretch"; - break; - } - std::string OSDM22 = - g_ActiveConfig.bCrop ? " (crop)" : ""; - std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" : - g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM"; - - // If there is more text than this we will have a collision - if (g_ActiveConfig.bShowFPS) - { - T1 += "\n\n"; - T2 += "\n\n"; - } - - // The rows - T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str())); - T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str())); - T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str())); - T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled")); - T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled")); - - // The latest changed setting in yellow - T1 += (OSDChoice == -1) ? T0.at(0) : "\n"; - T1 += (OSDChoice == -2) ? T0.at(1) : "\n"; - T1 += (OSDChoice == -3) ? T0.at(2) : "\n"; - T1 += (OSDChoice == -4) ? T0.at(3) : "\n"; - T1 += (OSDChoice == -5) ? T0.at(4) : "\n"; - - // The other settings in cyan - T2 += (OSDChoice != -1) ? T0.at(0) : "\n"; - T2 += (OSDChoice != -2) ? T0.at(1) : "\n"; - T2 += (OSDChoice != -3) ? T0.at(2) : "\n"; - T2 += (OSDChoice != -4) ? T0.at(3) : "\n"; - T2 += (OSDChoice != -5) ? T0.at(4) : "\n"; - - // Render a shadow, and then the text - Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00); - Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000); - Renderer::RenderText(T2.c_str(), 20, 20, 0xFF00FFFF); - } - } } void Renderer::RenderText(const char *text, int left, int top, u32 color) { - int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth(); - int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight(); + const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth(); + const int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight(); + glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f, ((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f); + s_pfont->printMultilineText(text, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, 0, nBackbufferWidth, nBackbufferHeight); + GL_REPORT_ERRORD(); } @@ -768,27 +610,6 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) return result; } -void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) -{ - if (!fbWidth || !fbHeight) - return; - s_skipSwap = g_bSkipCurrentFrame; - VideoFifo_CheckEFBAccess(); - VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); - XFBWrited = true; - // XXX: Without the VI, how would we know what kind of field this is? So - // just use progressive. - if (g_ActiveConfig.bUseXFB) - { - FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); - } - else - { - Renderer::Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); - } -} - // Function: This function handles the OpenGL glScissor() function // ---------------------------- // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg() @@ -801,39 +622,38 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect // therefore the width and height are (scissorBR + 1) - scissorTL bool Renderer::SetScissorRect() { - int xoff = bpmem.scissorOffset.x * 2 - 342; - int yoff = bpmem.scissorOffset.y * 2 - 342; - float rc_left = (float)bpmem.scissorTL.x - xoff - 342; // left = 0 - float rc_top = (float)bpmem.scissorTL.y - yoff - 342; // right = 0 - float rc_right = (float)bpmem.scissorBR.x - xoff - 341; // right = 640 - float rc_bottom = (float)bpmem.scissorBR.y - yoff - 341; // bottom = 480 + MathUtil::Rectangle rc; + GetScissorRect(rc); - if (rc_left < 0) rc_left = 0; - if (rc_right > EFB_WIDTH) rc_right = EFB_WIDTH; - if (rc_top < 0) rc_top = 0; - if (rc_bottom > EFB_HEIGHT) rc_bottom = EFB_HEIGHT; + if (rc.left < 0) rc.left = 0; - if (rc_left > rc_right) + if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH; + + if (rc.top < 0) rc.top = 0; + + if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT; + + if (rc.left > rc.right) { - int temp = rc_right; - rc_right = rc_left; - rc_left = temp; + int temp = rc.right; + rc.right = rc.left; + rc.left = temp; } - if (rc_top > rc_bottom) + if (rc.top > rc.bottom) { - int temp = rc_bottom; - rc_bottom = rc_top; - rc_top = temp; + int temp = rc.bottom; + rc.bottom = rc.top; + rc.top = temp; } // Check that the coordinates are good - if (rc_right != rc_left && rc_bottom != rc_top) + if (rc.right != rc.left && rc.bottom != rc.top) { glScissor( - (int)(rc_left * EFBxScale), // x = 0 for example - (int)((EFB_HEIGHT - rc_bottom) * EFByScale), // y = 0 for example - (int)((rc_right - rc_left)* EFBxScale), // width = 640 for example - (int)((rc_bottom - rc_top) * EFByScale) // height = 480 for example + (int)(rc.left * EFBxScale), // x = 0 for example + (int)((EFB_HEIGHT - rc.bottom) * EFByScale), // y = 0 for example + (int)((rc.right - rc.left)* EFBxScale), // width = 640 for example + (int)((rc.bottom - rc.top) * EFByScale) // height = 480 for example ); return true; } @@ -962,7 +782,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) } // Called from VertexShaderManager -void UpdateViewport() +void Renderer::UpdateViewport() { // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) // [0] = width/2 @@ -979,10 +799,10 @@ void UpdateViewport() // int Ystride = (s_Fulltarget_height - s_target_height) / 2; // Stretch picture with increased internal resolution - int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * EFBxScale); - int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * EFByScale); - int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale); - int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale); + int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * Renderer::GetTargetScaleX()); + int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * Renderer::GetTargetScaleY()); + int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX()); + int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY()); double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; double GLFar = xfregs.rawViewport[5] / 16777216.0f; if (Width < 0) @@ -1131,8 +951,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons return; } - DVSTARTPROFILE(); ResetAPIState(); + + DVSTARTPROFILE(); TargetRectangle dst_rect; ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect); @@ -1281,10 +1102,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (s_bScreenshot) { s_criticalScreenshot.Enter(); - // Save screenshot - SaveRenderTarget(s_sScreenshotName.c_str(), dst_rect); + SaveScreenshot(s_sScreenshotName, dst_rect); // Reset settings - s_sScreenshotName = ""; + s_sScreenshotName.clear(); s_bScreenshot = false; s_criticalScreenshot.Leave(); } @@ -1438,33 +1258,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height; } - switch(s_LastEFBScale) + if (CalculateTargetSize()) { - case 0: - EFBxScale = xScale; - EFByScale = yScale; - break; - case 1: - EFBxScale = ceilf(xScale); - EFByScale = ceilf(yScale); - break; - default: - EFBxScale = (float)(g_ActiveConfig.iEFBScale - 1); - EFByScale = EFBxScale; - break; - }; - - int m_newFrameBufferWidth = EFB_WIDTH * EFBxScale; - int m_newFrameBufferHeight = EFB_HEIGHT * EFByScale; - if(m_newFrameBufferWidth != s_target_width || - m_newFrameBufferHeight != s_target_height ) - { - s_target_width = m_newFrameBufferWidth; - s_target_height = m_newFrameBufferHeight; - - s_Fulltarget_width = s_target_width; - s_Fulltarget_height = s_target_height; - delete g_framebuffer_manager; g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height, s_MSAASamples, s_MSAACoverageSamples); @@ -1559,7 +1354,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // For testing zbuffer targets. // Renderer::SetZBufferRender(); // SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, - // GetTargetWidth(), GetTargetHeight()); + // GetTargetWidth(), GetTargetHeight()); g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB); XFBWrited = false; } @@ -1668,15 +1463,6 @@ void Renderer::SetInterlacingMode() // TODO } -// Save screenshot -void Renderer::SetScreenshot(const char *filename) -{ - s_criticalScreenshot.Enter(); - s_sScreenshotName = filename; - s_bScreenshot = true; - s_criticalScreenshot.Leave(); -} - void Renderer::FlipImageData(u8 *data, int w, int h) { // Flip image upside down. Damn OpenGL. @@ -1691,6 +1477,8 @@ void Renderer::FlipImageData(u8 *data, int w, int h) } } +} + #if defined(HAVE_WX) && HAVE_WX THREAD_RETURN TakeScreenshot(void *pArgs) { @@ -1739,7 +1527,10 @@ THREAD_RETURN TakeScreenshot(void *pArgs) } #endif -bool Renderer::SaveRenderTarget(const char *filename, TargetRectangle back_rc) +namespace OGL +{ + +bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &back_rc) { u32 W = back_rc.GetWidth(); u32 H = back_rc.GetHeight(); @@ -1769,7 +1560,7 @@ bool Renderer::SaveRenderTarget(const char *filename, TargetRectangle back_rc) } ScrStrct *threadStruct = new ScrStrct; - threadStruct->filename = std::string(filename); + threadStruct->filename = filename; threadStruct->img = a; threadStruct->H = H; threadStruct->W = W; @@ -1782,9 +1573,11 @@ bool Renderer::SaveRenderTarget(const char *filename, TargetRectangle back_rc) OSD::AddMessage("Saving Screenshot... ", 2000); #else - bool result = SaveTGA(filename, W, H, data); + bool result = SaveTGA(filename.c_str(), W, H, data); delete[] data; #endif return result; } + +} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h new file mode 100644 index 0000000000..3747c38f28 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -0,0 +1,49 @@ + +#ifndef _RENDER_H_ +#define _RENDER_H_ + +#include "RenderBase.h" + +namespace OGL +{ + +class Renderer : public ::Renderer +{ +public: + Renderer(); + ~Renderer(); + + void SetColorMask(); + void SetBlendMode(bool forceUpdate); + bool SetScissorRect(); + void SetGenerationMode(); + void SetDepthMode(); + void SetLogicOpMode(); + void SetDitherMode(); + void SetLineWidth(); + void SetSamplerState(int stage,int texindex); + void SetInterlacingMode(); + + void RenderText(const char* pstr, int left, int top, u32 color); + void DrawDebugInfo(); + void FlipImageData(u8 *data, int w, int h); + + u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data); + + void ResetAPIState(); + void RestoreAPIState(); + + TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); + + void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc); + + void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); + + void UpdateViewport(); + + bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); +}; + +} + +#endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript index c8068c888a..b1a60c6759 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript +++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript @@ -7,7 +7,6 @@ import sys name = os.sep + "Plugin_VideoOGL" files = [ - 'BPFunctions.cpp', 'RasterFont.cpp', 'Render.cpp', 'TextureCache.cpp', diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 0b2f7419dc..c8013ef027 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -305,7 +305,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation GL_REPORT_ERRORD(); - TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect); + TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect); glBegin(GL_QUADS); glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 5c614ed5e3..82124a86b3 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -308,13 +308,13 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf cacheBytes = 64; int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); - Renderer::ResetAPIState(); + g_renderer->ResetAPIState(); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureCache::DisableStage(0); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); } @@ -386,13 +386,13 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) { - Renderer::ResetAPIState(); + g_renderer->ResetAPIState(); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); FramebufferManager::SetFramebuffer(0); VertexShaderManager::SetViewportChanged(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureCache::DisableStage(0); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); } @@ -409,7 +409,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur int srcFmtWidth = srcWidth / 2; - Renderer::ResetAPIState(); // reset any game specific settings + g_renderer->ResetAPIState(); // reset any game specific settings // switch to texture converter frame buffer // attach destTexture as color destination @@ -462,7 +462,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur FramebufferManager::SetFramebuffer(0); - Renderer::RestoreAPIState(); + g_renderer->RestoreAPIState(); GL_REPORT_ERRORD(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index af274520ba..bf0482ecd8 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -198,12 +198,12 @@ void VertexManager::vFlush() { // If host supports GL_ARB_blend_func_extended, we can do dst alpha in // the same pass as regular rendering. - Renderer::SetBlendMode(true); + g_renderer->SetBlendMode(true); ps = PixelShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components); } else { - Renderer::SetBlendMode(true); + g_renderer->SetBlendMode(true); ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components); } } @@ -234,7 +234,7 @@ void VertexManager::vFlush() Draw(); // restore color mask - Renderer::SetColorMask(); + g_renderer->SetColorMask(); if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) glEnable(GL_BLEND); @@ -265,7 +265,7 @@ void VertexManager::vFlush() tr.right = Renderer::GetTargetWidth(); tr.top = 0; tr.bottom = Renderer::GetTargetHeight(); - Renderer::SaveRenderTarget(str, tr); + g_renderer->SaveScreenshot(str, tr); } #endif g_Config.iSaveTargetId++; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 6531c64478..0c1c48204f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -65,6 +65,7 @@ Make AA apply instantly during gameplay if possible #include "Debugger/Debugger.h" #endif // HAVE_WX +#include "MainBase.h" #include "VideoConfig.h" #include "LookUpTables.h" #include "ImageWrite.h" @@ -89,33 +90,16 @@ Make AA apply instantly during gameplay if possible #include "OnScreenDisplay.h" #include "Setup.h" #include "DLCache.h" +#include "FramebufferManager.h" #include "VideoState.h" -SVideoInitialize g_VideoInitialize; -PLUGIN_GLOBALS* globals = NULL; - // Logging int GLScissorX, GLScissorY, GLScissorW, GLScissorH; -static bool s_PluginInitialized = false; - -volatile u32 s_swapRequested = FALSE; #if defined(HAVE_X11) && HAVE_X11 static volatile u32 s_doStateRequested = FALSE; #endif -static u32 s_efbAccessRequested = FALSE; -static volatile u32 s_FifoShuttingDown = FALSE; - -static volatile struct -{ - u32 xfbAddr; - FieldType field; - u32 fbWidth; - u32 fbHeight; -} s_beginFieldArgs; - -static volatile EFBAccessType s_AccessEFBType; bool IsD3D() { @@ -236,11 +220,13 @@ void Initialize(void *init) void Video_Prepare() { OpenGL_MakeCurrent(); - if (!Renderer::Init()) { - g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE); - PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info"); - exit(1); - } + //if (!Renderer::Init()) { + // g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE); + // PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info"); + // exit(1); + //} + + g_renderer = new OGL::Renderer; s_efbAccessRequested = FALSE; s_FifoShuttingDown = FALSE; @@ -295,7 +281,7 @@ void Shutdown() delete g_vertex_manager; delete g_texture_cache; OpcodeDecoder_Shutdown(); - Renderer::Shutdown(); + delete g_renderer; OpenGL_Shutdown(); } @@ -348,195 +334,3 @@ void DoState(unsigned char **ptr, int mode) #endif check_DoState(); } - -void EmuStateChange(PLUGIN_EMUSTATE newState) -{ - Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); -} - -// Enter and exit the video loop -void Video_EnterLoop() -{ - Fifo_EnterLoop(g_VideoInitialize); -} - -void Video_ExitLoop() -{ - Fifo_ExitLoop(); - s_FifoShuttingDown = TRUE; -} - -void Video_SetRendering(bool bEnabled) -{ - Fifo_SetRendering(bEnabled); -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequest() -{ - if(g_ActiveConfig.bUseXFB) - { - if (Common::AtomicLoadAcquire(s_swapRequested)) - { - EFBRectangle rc; - Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); - Common::AtomicStoreRelease(s_swapRequested, FALSE); - } - } -} - -static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) -{ - return !((aLower >= bUpper) || (bLower >= aUpper)); -} - -// Run from the graphics thread (from Fifo.cpp) -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) -{ - if (g_ActiveConfig.bUseXFB) - { - if(Common::AtomicLoadAcquire(s_swapRequested)) - { - 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; - - if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) - VideoFifo_CheckSwapRequest(); - } - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) -{ - if (s_PluginInitialized && g_ActiveConfig.bUseXFB) - { - if (!g_VideoInitialize.bOnThread) - VideoFifo_CheckSwapRequest(); - s_beginFieldArgs.xfbAddr = xfbAddr; - s_beginFieldArgs.field = field; - s_beginFieldArgs.fbWidth = fbWidth; - s_beginFieldArgs.fbHeight = fbHeight; - } -} - -// Run from the CPU thread (from VideoInterface.cpp) -void Video_EndField() -{ - if (s_PluginInitialized) - { - Common::AtomicStoreRelease(s_swapRequested, TRUE); - } -} - -void Video_AddMessage(const char* pstr, u32 milliseconds) -{ - OSD::AddMessage(pstr, milliseconds); -} - -// Screenshot -void Video_Screenshot(const char *_szFilename) -{ - Renderer::SetScreenshot(_szFilename); -} - -static struct -{ - EFBAccessType type; - u32 x; - u32 y; - u32 Data; -} s_accessEFBArgs; - -static u32 s_AccessEFBResult = 0; - -void VideoFifo_CheckEFBAccess() -{ - if (Common::AtomicLoadAcquire(s_efbAccessRequested)) - { - s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data); - - Common::AtomicStoreRelease(s_efbAccessRequested, FALSE); - } -} - -u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) -{ - if (s_PluginInitialized) - { - s_accessEFBArgs.type = type; - s_accessEFBArgs.x = x; - s_accessEFBArgs.y = y; - s_accessEFBArgs.Data = InputData; - - Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); - - if (g_VideoInitialize.bOnThread) - { - while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown) - //Common::SleepCurrentThread(1); - Common::YieldCPU(); - } - else - VideoFifo_CheckEFBAccess(); - - return s_AccessEFBResult; - } - - return 0; -} - -void VideoFifo_CheckAsyncRequest() { - VideoFifo_CheckSwapRequest(); - VideoFifo_CheckEFBAccess(); -#if defined(HAVE_X11) && HAVE_X11 - check_DoState(); -#endif -} - -void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) -{ - CommandProcessor::Read16(_rReturnValue, _Address); -} - -void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address) -{ - CommandProcessor::Write16(_Data, _Address); -} - -void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address) -{ - PixelEngine::Read16(_rReturnValue, _Address); -} - -void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address) -{ - PixelEngine::Write16(_Data, _Address); -} - -void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address) -{ - PixelEngine::Write32(_Data, _Address); -} - -void Video_GatherPipeBursted(void) -{ - CommandProcessor::GatherPipeBursted(); -} - -void Video_WaitForFrameFinish(void) -{ - CommandProcessor::WaitForFrameFinish(); -} - -bool Video_IsFifoBusy(void) -{ - return CommandProcessor::isFifoBusy; -} - -void Video_AbortFrame(void) -{ - CommandProcessor::AbortFrame(); -} diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.h b/Source/Plugins/Plugin_VideoOGL/Src/main.h index 1715657d18..99f8928fa6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.h @@ -19,10 +19,8 @@ #define _MAIN_H_ #include "pluginspecs_video.h" +#include "MainBase.h" extern SVideoInitialize g_VideoInitialize; -extern volatile u32 s_swapRequested; -void VideoFifo_CheckEFBAccess(); -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif // _MAIN_H_