diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2010-11-18 02:21:26 +0000 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2010-11-18 02:21:26 +0000 |
| commit | 159ed43f677ed62097569244882c0a9ddffa7a67 (patch) | |
| tree | bb49f2f233f9b4039d754f756de31e3ea488a84b /Source/Core/VideoCommon | |
| parent | 054358380e578c6f33fc1dd343fad552d0c47256 (diff) | |
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
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/BPFunctions.cpp | 140 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/BPStructs.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/FramebufferManagerBase.cpp | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/FramebufferManagerBase.h | 4 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/MainBase.cpp | 214 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/MainBase.h | 15 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/OnScreenDisplay.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/Render.h | 100 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/RenderBase.cpp | 264 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/RenderBase.h | 165 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/SConscript | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexManagerBase.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VideoCommon.h | 9 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/VideoCommon.vcproj | 24 |
16 files changed, 844 insertions, 120 deletions
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/Core/VideoCommon/Src/BPFunctions.cpp b/Source/Core/VideoCommon/Src/BPFunctions.cpp new file mode 100644 index 0000000000..9e2c99b6db --- /dev/null +++ b/Source/Core/VideoCommon/Src/BPFunctions.cpp @@ -0,0 +1,140 @@ +// 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 "RenderBase.h" +#include "TextureCacheBase.h" +#include "VertexManagerBase.h" +#include "VertexShaderManager.h" +#include "VideoConfig.h" + +bool textureChanged[8]; +const bool renderFog = false; + +namespace BPFunctions +{ +// ---------------------------------------------- +// State translation lookup tables +// Reference: Yet Another Gamecube Documentation +// ---------------------------------------------- + + +void FlushPipeline() +{ + VertexManager::Flush(); +} + +void SetGenerationMode(const BPCmd &bp) +{ + g_renderer->SetGenerationMode(); +} + +void SetScissor(const BPCmd &bp) +{ + g_renderer->SetScissorRect(); +} + +void SetLineWidth(const BPCmd &bp) +{ + g_renderer->SetLineWidth(); +} + +void SetDepthMode(const BPCmd &bp) +{ + g_renderer->SetDepthMode(); +} + +void SetBlendMode(const BPCmd &bp) +{ + g_renderer->SetBlendMode(false); +} +void SetDitherMode(const BPCmd &bp) +{ + g_renderer->SetDitherMode(); +} +void SetLogicOpMode(const BPCmd &bp) +{ + g_renderer->SetLogicOpMode(); +} + +void SetColorMask(const BPCmd &bp) +{ + 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) +{ + // 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; + + g_renderer->ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z); + } +} + +void RestoreRenderState(const BPCmd &bp) +{ + g_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) +{ + g_renderer->SetSamplerState(bp.address & 3, (bp.address & 0xE0) == 0xA0); +} + +void SetInterlacingMode(const BPCmd &bp) +{ + // TODO +} + +}; 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 <list> 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 <cmath> +#include <string> + +// 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 <string> + +// 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 <typename R> +void GetScissorRect(MathUtil::Rectangle<R> &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<int> { #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 @@ -459,6 +459,10 @@ Name="Register Sections" > <File + RelativePath=".\Src\BPFunctions.cpp" + > + </File> + <File RelativePath=".\Src\BPFunctions.h" > </File> @@ -739,6 +743,22 @@ > </File> <File + RelativePath=".\Src\MainBase.cpp" + > + </File> + <File + RelativePath=".\Src\MainBase.h" + > + </File> + <File + RelativePath=".\Src\RenderBase.cpp" + > + </File> + <File + RelativePath=".\Src\RenderBase.h" + > + </File> + <File RelativePath=".\Src\TextureCacheBase.cpp" > </File> @@ -780,10 +800,6 @@ > </File> <File - RelativePath=".\Src\Render.h" - > - </File> - <File RelativePath=".\Src\SConscript" > </File> |
