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
This commit is contained in:
Jordan Woyak
2010-11-18 02:21:26 +00:00
parent 054358380e
commit 159ed43f67
45 changed files with 1180 additions and 1959 deletions

View File

@ -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 &copyfmt, 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
}
};

View File

@ -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"

View File

@ -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)

View File

@ -1,6 +1,6 @@
#ifndef _FRAMEBUFFERMANAGER_H
#define _FRAMEBUFFERMANAGER_H
#ifndef _FRAMEBUFFERMANAGERBASE_H
#define _FRAMEBUFFERMANAGERBASE_H
#include <list>

View File

@ -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();
}

View File

@ -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

View File

@ -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)

View File

@ -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_

View File

@ -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();
}

View File

@ -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_

View File

@ -29,7 +29,9 @@ files = [
'VertexLoader_TextCoord.cpp',
'TextureConversionShader.cpp',
'ImageWrite.cpp',
'MainBase.cpp',
'FramebufferManagerBase.cpp',
'RenderBase.cpp',
'VertexManagerBase.cpp',
'TextureCacheBase.cpp',
'Statistics.cpp',

View File

@ -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();
}

View File

@ -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"

View File

@ -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
};