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:
parent
054358380e
commit
159ed43f67
|
@ -1,4 +1,5 @@
|
||||||
set(SRCS Src/BPMemory.cpp
|
set(SRCS Src/BPMemory.cpp
|
||||||
|
Src/BPFunctions.cpp
|
||||||
Src/BPStructs.cpp
|
Src/BPStructs.cpp
|
||||||
Src/CommandProcessor.cpp
|
Src/CommandProcessor.cpp
|
||||||
Src/CPMemory.cpp
|
Src/CPMemory.cpp
|
||||||
|
@ -8,6 +9,7 @@ set(SRCS Src/BPMemory.cpp
|
||||||
Src/HiresTextures.cpp
|
Src/HiresTextures.cpp
|
||||||
Src/ImageWrite.cpp
|
Src/ImageWrite.cpp
|
||||||
Src/IndexGenerator.cpp
|
Src/IndexGenerator.cpp
|
||||||
|
Src/MainBase.cpp
|
||||||
Src/memcpy_amd.cpp
|
Src/memcpy_amd.cpp
|
||||||
Src/OnScreenDisplay.cpp
|
Src/OnScreenDisplay.cpp
|
||||||
Src/OpcodeDecoding.cpp
|
Src/OpcodeDecoding.cpp
|
||||||
|
@ -15,6 +17,7 @@ set(SRCS Src/BPMemory.cpp
|
||||||
Src/PixelShaderGen.cpp
|
Src/PixelShaderGen.cpp
|
||||||
Src/PixelShaderManager.cpp
|
Src/PixelShaderManager.cpp
|
||||||
Src/Profiler.cpp
|
Src/Profiler.cpp
|
||||||
|
Src/RenderBase.cpp
|
||||||
Src/Statistics.cpp
|
Src/Statistics.cpp
|
||||||
Src/TextureCacheBase.cpp
|
Src/TextureCacheBase.cpp
|
||||||
Src/TextureConversionShader.cpp
|
Src/TextureConversionShader.cpp
|
||||||
|
|
|
@ -17,18 +17,15 @@
|
||||||
|
|
||||||
#include "BPFunctions.h"
|
#include "BPFunctions.h"
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "D3DBase.h"
|
#include "RenderBase.h"
|
||||||
#include "Debugger/Debugger.h"
|
#include "TextureCacheBase.h"
|
||||||
#include "TextureCache.h"
|
#include "VertexManagerBase.h"
|
||||||
#include "VertexManager.h"
|
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
bool textureChanged[8];
|
bool textureChanged[8];
|
||||||
const bool renderFog = false;
|
const bool renderFog = false;
|
||||||
|
|
||||||
using namespace D3D;
|
|
||||||
|
|
||||||
namespace BPFunctions
|
namespace BPFunctions
|
||||||
{
|
{
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
|
@ -44,40 +41,40 @@ void FlushPipeline()
|
||||||
|
|
||||||
void SetGenerationMode(const BPCmd &bp)
|
void SetGenerationMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetGenerationMode();
|
g_renderer->SetGenerationMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScissor(const BPCmd &bp)
|
void SetScissor(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetScissorRect();
|
g_renderer->SetScissorRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLineWidth(const BPCmd &bp)
|
void SetLineWidth(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetLineWidth();
|
g_renderer->SetLineWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetDepthMode(const BPCmd &bp)
|
void SetDepthMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetDepthMode();
|
g_renderer->SetDepthMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBlendMode(const BPCmd &bp)
|
void SetBlendMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetBlendMode(false);
|
g_renderer->SetBlendMode(false);
|
||||||
}
|
}
|
||||||
void SetDitherMode(const BPCmd &bp)
|
void SetDitherMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetDitherMode();
|
g_renderer->SetDitherMode();
|
||||||
}
|
}
|
||||||
void SetLogicOpMode(const BPCmd &bp)
|
void SetLogicOpMode(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::SetLogicOpMode();
|
g_renderer->SetLogicOpMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetColorMask(const BPCmd &bp)
|
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)
|
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 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||||
u32 z = bpmem.clearZValue;
|
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)
|
void RestoreRenderState(const BPCmd &bp)
|
||||||
{
|
{
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetConfig(const int &type)
|
bool GetConfig(const int &type)
|
||||||
|
@ -132,7 +129,7 @@ u8 *GetPointer(const u32 &address)
|
||||||
|
|
||||||
void SetTextureMode(const BPCmd &bp)
|
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)
|
void SetInterlacingMode(const BPCmd &bp)
|
|
@ -20,7 +20,7 @@
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "Render.h"
|
#include "RenderBase.h"
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "PixelEngine.h"
|
#include "PixelEngine.h"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
#include "FramebufferManagerBase.h"
|
#include "FramebufferManagerBase.h"
|
||||||
|
|
||||||
#include "Render.h"
|
#include "RenderBase.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
|
|
||||||
FramebufferManagerBase *g_framebuffer_manager;
|
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->srcWidth = vxfb->xfbWidth = fbWidth;
|
||||||
vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight;
|
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
|
// keep stale XFB data from being used
|
||||||
ReplaceVirtualXFB();
|
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
|
// Copy EFB data to XFB and restore render target again
|
||||||
vxfb->xfbSource->CopyEFB();
|
vxfb->xfbSource->CopyEFB();
|
||||||
|
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
FramebufferManagerBase::VirtualXFBListType::iterator FramebufferManagerBase::FindVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
#ifndef _FRAMEBUFFERMANAGER_H
|
#ifndef _FRAMEBUFFERMANAGERBASE_H
|
||||||
#define _FRAMEBUFFERMANAGER_H
|
#define _FRAMEBUFFERMANAGERBASE_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
|
@ -20,7 +20,7 @@
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
#include "OnScreenDisplay.h"
|
#include "OnScreenDisplay.h"
|
||||||
#include "Render.h"
|
#include "RenderBase.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
|
||||||
namespace OSD
|
namespace OSD
|
||||||
|
@ -64,8 +64,8 @@ void DrawMessages()
|
||||||
|
|
||||||
alpha <<= 24;
|
alpha <<= 24;
|
||||||
|
|
||||||
Renderer::RenderText(it->str, left+1, top+1, 0x000000|alpha);
|
g_renderer->RenderText(it->str, left+1, top+1, 0x000000|alpha);
|
||||||
Renderer::RenderText(it->str, left, top, 0xffff30|alpha);
|
g_renderer->RenderText(it->str, left, top, 0xffff30|alpha);
|
||||||
top += 15;
|
top += 15;
|
||||||
|
|
||||||
if (time_left <= 0)
|
if (time_left <= 0)
|
||||||
|
|
|
@ -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_
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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_
|
|
@ -29,7 +29,9 @@ files = [
|
||||||
'VertexLoader_TextCoord.cpp',
|
'VertexLoader_TextCoord.cpp',
|
||||||
'TextureConversionShader.cpp',
|
'TextureConversionShader.cpp',
|
||||||
'ImageWrite.cpp',
|
'ImageWrite.cpp',
|
||||||
|
'MainBase.cpp',
|
||||||
'FramebufferManagerBase.cpp',
|
'FramebufferManagerBase.cpp',
|
||||||
|
'RenderBase.cpp',
|
||||||
'VertexManagerBase.cpp',
|
'VertexManagerBase.cpp',
|
||||||
'TextureCacheBase.cpp',
|
'TextureCacheBase.cpp',
|
||||||
'Statistics.cpp',
|
'Statistics.cpp',
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Statistics.h"
|
#include "Statistics.h"
|
||||||
#include "HiresTextures.h"
|
#include "HiresTextures.h"
|
||||||
#include "Render.h"
|
#include "RenderBase.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
|
|
||||||
|
@ -668,9 +668,9 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||||
|
|
||||||
entry->frameCount = frameCount;
|
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);
|
entry->FromRenderTarget(bFromZBuffer, bScaleByHalf, cbufid, colmat, source_rect, bIsIntensityFmt, copyfmt);
|
||||||
|
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
#include "TextureCacheBase.h"
|
#include "TextureCacheBase.h"
|
||||||
#include "Render.h"
|
#include "RenderBase.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
|
|
||||||
#include "VertexManagerBase.h"
|
#include "VertexManagerBase.h"
|
||||||
|
|
|
@ -59,7 +59,6 @@ enum
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
|
|
||||||
|
|
||||||
inline u8 *Memory_GetPtr(u32 _uAddress)
|
inline u8 *Memory_GetPtr(u32 _uAddress)
|
||||||
{
|
{
|
||||||
return g_VideoInitialize.pGetMemoryPointer(_uAddress);
|
return g_VideoInitialize.pGetMemoryPointer(_uAddress);
|
||||||
|
@ -123,10 +122,16 @@ struct TargetRectangle : public MathUtil::Rectangle<int>
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Only used by D3D plugin.
|
// Only used by D3D plugin.
|
||||||
const RECT *AsRECT() const {
|
const RECT *AsRECT() const
|
||||||
|
{
|
||||||
// The types are binary compatible so this works.
|
// The types are binary compatible so this works.
|
||||||
return (const RECT *)this;
|
return (const RECT *)this;
|
||||||
}
|
}
|
||||||
|
RECT *AsRECT()
|
||||||
|
{
|
||||||
|
// The types are binary compatible so this works.
|
||||||
|
return (RECT *)this;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -458,6 +458,10 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Register Sections"
|
Name="Register Sections"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\BPFunctions.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\BPFunctions.h"
|
RelativePath=".\Src\BPFunctions.h"
|
||||||
>
|
>
|
||||||
|
@ -738,6 +742,22 @@
|
||||||
RelativePath=".\Src\FramebufferManagerBase.h"
|
RelativePath=".\Src\FramebufferManagerBase.h"
|
||||||
>
|
>
|
||||||
</File>
|
</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
|
<File
|
||||||
RelativePath=".\Src\TextureCacheBase.cpp"
|
RelativePath=".\Src\TextureCacheBase.cpp"
|
||||||
>
|
>
|
||||||
|
@ -779,10 +799,6 @@
|
||||||
RelativePath=".\Src\PixelEngine.h"
|
RelativePath=".\Src\PixelEngine.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\Src\Render.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\SConscript"
|
RelativePath=".\Src\SConscript"
|
||||||
>
|
>
|
||||||
|
|
|
@ -63,13 +63,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "Core\Common\Commo
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dolphin", "Core\DolphinWX\DolphinWX.vcproj", "{A72606EF-C5C1-4954-90AD-F0F93A8D97D9}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{21DBE606-2958-43AC-A14E-B6B798D56554} = {21DBE606-2958-43AC-A14E-B6B798D56554}
|
|
||||||
{C7E5D50A-2916-464B-86A7-E10B3CC88ADA} = {C7E5D50A-2916-464B-86A7-E10B3CC88ADA}
|
{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}
|
{D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8} = {D6E56527-BBB9-4EAD-A6EC-49D4BF6AFCD8}
|
||||||
{D4833C30-FA5F-4DFE-BD32-109DE1F09ED1} = {D4833C30-FA5F-4DFE-BD32-109DE1F09ED1}
|
{D4833C30-FA5F-4DFE-BD32-109DE1F09ED1} = {D4833C30-FA5F-4DFE-BD32-109DE1F09ED1}
|
||||||
{05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75}
|
{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}
|
{33546D62-7F34-4EA6-A88E-D538B36E16BF} = {33546D62-7F34-4EA6-A88E-D538B36E16BF}
|
||||||
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
{11F55366-12EC-4C44-A8CB-1D4E315D61ED} = {11F55366-12EC-4C44-A8CB-1D4E315D61ED}
|
||||||
{3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
|
{3E03C179-8251-46E4-81F4-466F114BAC63} = {3E03C179-8251-46E4-81F4-466F114BAC63}
|
||||||
|
|
|
@ -739,6 +739,10 @@
|
||||||
RelativePath=".\Src\Render.cpp"
|
RelativePath=".\Src\Render.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\Render.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureCache.cpp"
|
RelativePath=".\Src\TextureCache.cpp"
|
||||||
>
|
>
|
||||||
|
@ -816,14 +820,6 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Decoder"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\BPFunctions.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\Globals.h"
|
RelativePath=".\Src\Globals.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -49,37 +49,9 @@
|
||||||
|
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
|
||||||
int frameCount = 0;
|
|
||||||
static int s_fps = 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_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;
|
ID3D11Buffer* access_efb_cbuf = NULL;
|
||||||
ID3D11BlendState* clearblendstates[4] = {NULL};
|
ID3D11BlendState* clearblendstates[4] = {NULL};
|
||||||
|
@ -250,16 +222,16 @@ void SetupDeviceObjects()
|
||||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)access_efb_cbuf, "constant buffer for Renderer::AccessEFB");
|
D3D::SetDebugObjectName((ID3D11DeviceChild*)access_efb_cbuf, "constant buffer for Renderer::AccessEFB");
|
||||||
|
|
||||||
D3D11_DEPTH_STENCIL_DESC ddesc;
|
D3D11_DEPTH_STENCIL_DESC ddesc;
|
||||||
ddesc.DepthEnable = FALSE;
|
ddesc.DepthEnable = FALSE;
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
ddesc.StencilEnable = FALSE;
|
ddesc.StencilEnable = FALSE;
|
||||||
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
ddesc.DepthEnable = TRUE;
|
ddesc.DepthEnable = TRUE;
|
||||||
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
|
||||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
|
@ -299,10 +271,10 @@ void SetupDeviceObjects()
|
||||||
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]);
|
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]);
|
||||||
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
|
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
|
||||||
|
|
||||||
ddesc.DepthEnable = FALSE;
|
ddesc.DepthEnable = FALSE;
|
||||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||||
ddesc.DepthFunc = D3D11_COMPARISON_LESS;
|
ddesc.DepthFunc = D3D11_COMPARISON_LESS;
|
||||||
ddesc.StencilEnable = FALSE;
|
ddesc.StencilEnable = FALSE;
|
||||||
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
||||||
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
||||||
hr = D3D::device->CreateDepthStencilState(&ddesc, &resetdepthstate);
|
hr = D3D::device->CreateDepthStencilState(&ddesc, &resetdepthstate);
|
||||||
|
@ -334,9 +306,11 @@ void TeardownDeviceObjects()
|
||||||
SAFE_RELEASE(resetraststate);
|
SAFE_RELEASE(resetraststate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::Init()
|
namespace DX11
|
||||||
|
{
|
||||||
|
|
||||||
|
Renderer::Renderer()
|
||||||
{
|
{
|
||||||
UpdateActiveConfig();
|
|
||||||
int x, y, w_temp, h_temp;
|
int x, y, w_temp, h_temp;
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
|
|
||||||
|
@ -357,26 +331,7 @@ bool Renderer::Init()
|
||||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
switch(s_LastEFBScale)
|
CalculateTargetSize();
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
SetupDeviceObjects();
|
SetupDeviceObjects();
|
||||||
|
|
||||||
|
@ -396,10 +351,9 @@ bool Renderer::Init()
|
||||||
D3D::gfxstate->rastdesc.ScissorEnable = TRUE;
|
D3D::gfxstate->rastdesc.ScissorEnable = TRUE;
|
||||||
|
|
||||||
reset_called = false;
|
reset_called = false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shutdown()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
TeardownDeviceObjects();
|
TeardownDeviceObjects();
|
||||||
D3D::EndFrame();
|
D3D::EndFrame();
|
||||||
|
@ -407,100 +361,6 @@ void Renderer::Shutdown()
|
||||||
D3D::Close();
|
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<std::string> 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)
|
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);
|
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;
|
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
TargetRectangle result;
|
TargetRectangle result;
|
||||||
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
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.right = (int)(rc.right * EFBxScale) + Xstride;
|
||||||
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
|
result.bottom = (int)(rc.bottom * EFByScale) + Ystride;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// With D3D, we have to resize the backbuffer if the window changed
|
// With D3D, we have to resize the backbuffer if the window changed
|
||||||
// size.
|
// size.
|
||||||
void CheckForResize()
|
bool Renderer::CheckForResize()
|
||||||
{
|
{
|
||||||
while (EmuWindow::IsSizing())
|
while (EmuWindow::IsSizing())
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
|
@ -533,7 +392,7 @@ void CheckForResize()
|
||||||
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
||||||
int width = rcParentWindow.right - rcParentWindow.left;
|
int width = rcParentWindow.right - rcParentWindow.left;
|
||||||
int height = rcParentWindow.bottom - rcParentWindow.top;
|
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);
|
MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||||
}
|
}
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
|
@ -542,62 +401,43 @@ void CheckForResize()
|
||||||
int client_height = rcWindow.bottom - rcWindow.top;
|
int client_height = rcWindow.bottom - rcWindow.top;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if ((client_width != s_backbuffer_width ||
|
if ((client_width != Renderer::GetBackbufferWidth() ||
|
||||||
client_height != s_backbuffer_height) &&
|
client_height != Renderer::GetBackbufferHeight()) &&
|
||||||
client_width >= 4 && client_height >= 4)
|
client_width >= 4 && client_height >= 4)
|
||||||
{
|
{
|
||||||
WindowResized = true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
return false;
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::SetScissorRect()
|
bool Renderer::SetScissorRect()
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
TargetRectangle rc;
|
||||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
GetScissorRect(rc);
|
||||||
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);
|
|
||||||
|
|
||||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
|
|
||||||
rc.left = (int)(rc.left * EFBxScale);
|
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.right = (int)(rc.right * EFBxScale);
|
||||||
rc.bottom = (int)(rc.bottom * EFByScale);
|
rc.bottom = (int)(rc.bottom * EFByScale);
|
||||||
|
|
||||||
if (rc.left < 0) rc.left = 0;
|
if (rc.left < 0) rc.left = 0;
|
||||||
if (rc.right < 0) rc.right = 0;
|
if (rc.right < 0) rc.right = 0;
|
||||||
|
|
||||||
if (rc.left > s_target_width) rc.left = s_target_width;
|
if (rc.left > s_target_width) rc.left = s_target_width;
|
||||||
if (rc.right > s_target_width) rc.right = s_target_width;
|
if (rc.right > s_target_width) rc.right = s_target_width;
|
||||||
|
|
||||||
if (rc.top < 0) rc.top = 0;
|
if (rc.top < 0) rc.top = 0;
|
||||||
if (rc.bottom < 0) rc.bottom = 0;
|
if (rc.bottom < 0) rc.bottom = 0;
|
||||||
|
|
||||||
if (rc.top > s_target_height) rc.top = s_target_height;
|
if (rc.top > s_target_height) rc.top = s_target_height;
|
||||||
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
|
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
|
||||||
|
|
||||||
rc.left += Xstride;
|
rc.left += Xstride;
|
||||||
rc.top += Ystride;
|
rc.top += Ystride;
|
||||||
rc.right += Xstride;
|
rc.right += Xstride;
|
||||||
rc.bottom += Ystride;
|
rc.bottom += Ystride;
|
||||||
|
|
||||||
|
@ -616,14 +456,14 @@ bool Renderer::SetScissorRect()
|
||||||
|
|
||||||
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
||||||
{
|
{
|
||||||
D3D::context->RSSetScissorRects(1, &rc);
|
D3D::context->RSSetScissorRects(1, rc.AsRECT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
|
//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);
|
*rc.AsRECT() = CD3D11_RECT(Xstride, Ystride, Xstride + s_target_width, Ystride + s_target_height);
|
||||||
D3D::context->RSSetScissorRects(1, &rc);
|
D3D::context->RSSetScissorRects(1, rc.AsRECT());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
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::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), NULL);
|
||||||
D3D::drawColorQuad(rgbaColor, (float)RectToLock.left * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
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.right * 2.f / (float)Renderer::GetFullTargetWidth() - 1.f,
|
||||||
- (float)RectToLock.bottom * 2.f / (float)Renderer::GetFullTargetHeight() + 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
|
// Called from VertexShaderManager
|
||||||
void UpdateViewport()
|
void Renderer::UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
// [0] = width/2
|
// [0] = width/2
|
||||||
|
@ -777,20 +617,20 @@ void UpdateViewport()
|
||||||
// [3] = xorig + width/2 + 342
|
// [3] = xorig + width/2 + 342
|
||||||
// [4] = yorig + height/2 + 342
|
// [4] = yorig + height/2 + 342
|
||||||
// [5] = 16777215 * farz
|
// [5] = 16777215 * farz
|
||||||
const int old_fulltarget_w = s_Fulltarget_width;
|
const int old_fulltarget_w = Renderer::GetFullTargetWidth();
|
||||||
const int old_fulltarget_h = s_Fulltarget_height;
|
const int old_fulltarget_h = Renderer::GetFullTargetHeight();
|
||||||
|
|
||||||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||||
|
|
||||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
|
||||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
|
||||||
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride;
|
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)) * EFByScale) + Ystride;
|
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride;
|
||||||
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * EFBxScale);
|
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * Renderer::GetTargetScaleX());
|
||||||
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * EFByScale);
|
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * Renderer::GetTargetScaleY());
|
||||||
if (Width < 0)
|
if (Width < 0)
|
||||||
{
|
{
|
||||||
X += Width;
|
X += Width;
|
||||||
|
@ -822,16 +662,16 @@ void UpdateViewport()
|
||||||
if (sizeChanged)
|
if (sizeChanged)
|
||||||
{
|
{
|
||||||
// Make sure that the requested size is actually supported by the GFX driver
|
// 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
|
// 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
|
// 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;
|
newx *= (float)old_fulltarget_w / (float)Renderer::GetFullTargetWidth();
|
||||||
newy *= (float)old_fulltarget_h / (float)s_Fulltarget_height;
|
newy *= (float)old_fulltarget_h / (float)Renderer::GetFullTargetHeight();
|
||||||
newwidth *= (float)old_fulltarget_w / (float)s_Fulltarget_width;
|
newwidth *= (float)old_fulltarget_w / (float)Renderer::GetFullTargetWidth();
|
||||||
newheight *= (float)old_fulltarget_h / (float)s_Fulltarget_height;
|
newheight *= (float)old_fulltarget_h / (float)Renderer::GetFullTargetHeight();
|
||||||
|
|
||||||
s_Fulltarget_width = old_fulltarget_w;
|
s_Fulltarget_width = old_fulltarget_w;
|
||||||
s_Fulltarget_height = old_fulltarget_h;
|
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
|
// 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,
|
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;
|
1.f); // xfregs.rawViewport[5] / 16777216.0f;
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
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.
|
// 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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
// Prepare to copy the XFBs to our backbuffer
|
// Prepare to copy the XFBs to our backbuffer
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
|
@ -1015,31 +886,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
// done with drawing the game stuff, good moment to save a screenshot
|
// done with drawing the game stuff, good moment to save a screenshot
|
||||||
if (s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
// copy back buffer to system memory
|
SaveScreenshot(s_sScreenshotName, dst_rect);
|
||||||
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();
|
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,8 +920,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// Enable any configuration changes
|
// Enable any configuration changes
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
WindowResized = false;
|
const bool WindowResized = CheckForResize();
|
||||||
CheckForResize();
|
|
||||||
|
|
||||||
bool xfbchanged = false;
|
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;
|
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
switch(s_LastEFBScale)
|
CalculateTargetSize();
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
|
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 (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_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 if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_MIP_LINEAR);
|
||||||
}
|
}
|
||||||
else // point mag filter
|
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_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);
|
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 (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_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 if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR);
|
||||||
}
|
}
|
||||||
else // point mag filter
|
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_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);
|
else if (mip == TEXF_LINEAR) D3D::gfxstate->SetSamplerFilter(stage, D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR);
|
||||||
}
|
}
|
||||||
|
@ -1288,12 +1118,4 @@ void Renderer::SetInterlacingMode()
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save screenshot
|
|
||||||
void Renderer::SetScreenshot(const char *filename)
|
|
||||||
{
|
|
||||||
s_criticalScreenshot.Enter();
|
|
||||||
strcpy_s(s_sScreenshotName, filename);
|
|
||||||
s_bScreenshot = true;
|
|
||||||
s_criticalScreenshot.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -117,7 +117,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
unsigned int cbufid, const float colmat[], const EFBRectangle &source_rect,
|
||||||
bool bIsIntensityFmt, u32 copyfmt)
|
bool bIsIntensityFmt, u32 copyfmt)
|
||||||
{
|
{
|
||||||
Renderer::ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
// stretch picture with increased internal resolution
|
// stretch picture with increased internal resolution
|
||||||
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)virtualW, (float)virtualH);
|
||||||
D3D::context->RSSetViewports(1, &vp);
|
D3D::context->RSSetViewports(1, &vp);
|
||||||
|
@ -134,7 +134,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
}
|
}
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &efbcopycbuf[cbufid]);
|
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();
|
// TODO: try targetSource.asRECT();
|
||||||
const D3D11_RECT sourcerect = CD3D11_RECT(targetSource.left, targetSource.top, targetSource.right, targetSource.bottom);
|
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());
|
D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV());
|
||||||
|
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
TextureCache::TCacheEntryBase* TextureCache::CreateRenderTargetTexture(
|
||||||
|
|
|
@ -194,7 +194,7 @@ void VertexManager::vFlush()
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i))
|
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 FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||||
const TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
|
const TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
|
||||||
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "XFBConvert.h"
|
#include "XFBConvert.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
|
||||||
|
#include "MainBase.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "VideoConfigDiag.h"
|
#include "VideoConfigDiag.h"
|
||||||
|
@ -56,23 +57,6 @@
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
|
|
||||||
HINSTANCE g_hInstance = NULL;
|
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()
|
bool IsD3D()
|
||||||
{
|
{
|
||||||
|
@ -231,7 +215,7 @@ void Video_Prepare()
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
// internal interfaces
|
// internal interfaces
|
||||||
Renderer::Init();
|
g_renderer = new DX11::Renderer;
|
||||||
g_texture_cache = new DX11::TextureCache;
|
g_texture_cache = new DX11::TextureCache;
|
||||||
g_vertex_manager = new DX11::VertexManager;
|
g_vertex_manager = new DX11::VertexManager;
|
||||||
VertexShaderCache::Init();
|
VertexShaderCache::Init();
|
||||||
|
@ -276,7 +260,7 @@ void Shutdown()
|
||||||
VertexShaderCache::Shutdown();
|
VertexShaderCache::Shutdown();
|
||||||
delete g_vertex_manager;
|
delete g_vertex_manager;
|
||||||
delete g_texture_cache;
|
delete g_texture_cache;
|
||||||
Renderer::Shutdown();
|
delete g_renderer;
|
||||||
EmuWindow::Close();
|
EmuWindow::Close();
|
||||||
|
|
||||||
s_PluginInitialized = false;
|
s_PluginInitialized = false;
|
||||||
|
@ -292,187 +276,3 @@ void DoState(unsigned char **ptr, int mode)
|
||||||
PointerWrap p(ptr, mode);
|
PointerWrap p(ptr, mode);
|
||||||
VideoCommon_DoState(p);
|
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();
|
|
||||||
}
|
|
|
@ -20,10 +20,8 @@
|
||||||
|
|
||||||
#include "PluginSpecs_Video.h"
|
#include "PluginSpecs_Video.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
#include "MainBase.h"
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
extern volatile u32 s_swapRequested;
|
|
||||||
void VideoFifo_CheckEFBAccess();
|
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -675,14 +675,6 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Decoder"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Src\BPFunctions.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
<Filter
|
||||||
Name="Render"
|
Name="Render"
|
||||||
>
|
>
|
||||||
|
@ -710,6 +702,10 @@
|
||||||
RelativePath=".\Src\Render.cpp"
|
RelativePath=".\Src\Render.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\Render.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureCache.cpp"
|
RelativePath=".\Src\TextureCache.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -192,7 +192,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||||
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,27 +54,6 @@
|
||||||
|
|
||||||
static int s_fps = 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 int s_recordWidth;
|
static int s_recordWidth;
|
||||||
static int s_recordHeight;
|
static int s_recordHeight;
|
||||||
|
|
||||||
|
@ -83,18 +62,10 @@ static bool s_bAVIDumping;
|
||||||
|
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
static u32 s_LastAA;
|
static u32 s_LastAA;
|
||||||
static u32 s_LastEFBScale;
|
|
||||||
static bool IS_AMD;
|
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 char *st;
|
||||||
|
|
||||||
static bool s_bScreenshot = false;
|
|
||||||
static Common::CriticalSection s_criticalScreenshot;
|
|
||||||
static char s_sScreenshotName[1024];
|
|
||||||
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
|
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,11 +244,14 @@ void TeardownDeviceObjects()
|
||||||
TextureConverter::Shutdown();
|
TextureConverter::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace DX9
|
||||||
|
{
|
||||||
|
|
||||||
// Init functions
|
// Init functions
|
||||||
bool Renderer::Init()
|
Renderer::Renderer()
|
||||||
{
|
{
|
||||||
st = new char[32768];
|
st = new char[32768];
|
||||||
UpdateActiveConfig();
|
|
||||||
int fullScreenRes, x, y, w_temp, h_temp;
|
int fullScreenRes, x, y, w_temp, h_temp;
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
// Multisample Anti-aliasing hasn't been implemented yet use supersamling instead
|
// Multisample Anti-aliasing hasn't been implemented yet use supersamling instead
|
||||||
|
@ -321,32 +295,10 @@ bool Renderer::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
|
||||||
float SupersampleCoeficient = s_LastAA + 1;
|
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;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
EFByScale *= SupersampleCoeficient;
|
CalculateTargetSize(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_bLastFrameDumped = false;
|
s_bLastFrameDumped = false;
|
||||||
s_bAVIDumping = false;
|
s_bAVIDumping = false;
|
||||||
|
@ -384,10 +336,9 @@ bool Renderer::Init()
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
||||||
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Shutdown()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
TeardownDeviceObjects();
|
TeardownDeviceObjects();
|
||||||
D3D::EndFrame();
|
D3D::EndFrame();
|
||||||
|
@ -398,142 +349,7 @@ void Renderer::Shutdown()
|
||||||
{
|
{
|
||||||
AVIDump::Stop();
|
AVIDump::Stop();
|
||||||
}
|
}
|
||||||
delete [] st;
|
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<std::string> 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)
|
void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||||
|
@ -553,6 +369,8 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < h; y++)
|
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
|
// With D3D, we have to resize the backbuffer if the window changed
|
||||||
// size.
|
// size.
|
||||||
void CheckForResize()
|
bool Renderer::CheckForResize()
|
||||||
{
|
{
|
||||||
while (EmuWindow::IsSizing())
|
while (EmuWindow::IsSizing())
|
||||||
Sleep(10);
|
Sleep(10);
|
||||||
|
@ -581,17 +402,18 @@ void CheckForResize()
|
||||||
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
||||||
int width = rcParentWindow.right - rcParentWindow.left;
|
int width = rcParentWindow.right - rcParentWindow.left;
|
||||||
int height = rcParentWindow.bottom - rcParentWindow.top;
|
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);
|
MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
||||||
int client_width = rcWindow.right - rcWindow.left;
|
int client_width = rcWindow.right - rcWindow.left;
|
||||||
int client_height = rcWindow.bottom - rcWindow.top;
|
int client_height = rcWindow.bottom - rcWindow.top;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if ((client_width != s_backbuffer_width ||
|
if ((client_width != Renderer::GetBackbufferWidth() ||
|
||||||
client_height != s_backbuffer_height) &&
|
client_height != Renderer::GetBackbufferHeight()) &&
|
||||||
client_width >= 4 && client_height >= 4)
|
client_width >= 4 && client_height >= 4)
|
||||||
{
|
{
|
||||||
TeardownDeviceObjects();
|
TeardownDeviceObjects();
|
||||||
|
@ -601,47 +423,29 @@ void CheckForResize()
|
||||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||||
if(ScreenShootMEMSurface)
|
if(ScreenShootMEMSurface)
|
||||||
ScreenShootMEMSurface->Release();
|
ScreenShootMEMSurface->Release();
|
||||||
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(),
|
||||||
WindowResized = true;
|
D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
return true;
|
||||||
{
|
|
||||||
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()
|
bool Renderer::SetScissorRect()
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
TargetRectangle rc;
|
||||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
GetScissorRect(rc);
|
||||||
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);
|
|
||||||
|
|
||||||
if (rc.left < 0) rc.left = 0;
|
if (rc.left < 0) rc.left = 0;
|
||||||
if (rc.right < 0) rc.right = 0;
|
if (rc.right < 0) rc.right = 0;
|
||||||
|
|
||||||
if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
|
if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
|
||||||
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
|
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
|
||||||
|
|
||||||
if (rc.top < 0) rc.top = 0;
|
if (rc.top < 0) rc.top = 0;
|
||||||
if (rc.bottom < 0) rc.bottom = 0;
|
if (rc.bottom < 0) rc.bottom = 0;
|
||||||
|
|
||||||
if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
|
if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
|
||||||
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
|
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
|
||||||
|
|
||||||
|
@ -669,7 +473,7 @@ bool Renderer::SetScissorRect()
|
||||||
// Check that the coordinates are good
|
// Check that the coordinates are good
|
||||||
if (rc.right != rc.left && rc.bottom != rc.top)
|
if (rc.right != rc.left && rc.bottom != rc.top)
|
||||||
{
|
{
|
||||||
D3D::dev->SetScissorRect(&rc);
|
D3D::dev->SetScissorRect(rc.AsRECT());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -679,7 +483,7 @@ bool Renderer::SetScissorRect()
|
||||||
rc.top = Ystride;
|
rc.top = Ystride;
|
||||||
rc.right = Xstride + s_target_width;
|
rc.right = Xstride + s_target_width;
|
||||||
rc.bottom = Ystride + s_target_height;
|
rc.bottom = Ystride + s_target_height;
|
||||||
D3D::dev->SetScissorRect(&rc);
|
D3D::dev->SetScissorRect(rc.AsRECT());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -890,7 +694,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
void UpdateViewport()
|
void Renderer::UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
// [0] = width/2
|
// [0] = width/2
|
||||||
|
@ -899,22 +703,20 @@ void UpdateViewport()
|
||||||
// [3] = xorig + width/2 + 342
|
// [3] = xorig + width/2 + 342
|
||||||
// [4] = yorig + height/2 + 342
|
// [4] = yorig + height/2 + 342
|
||||||
// [5] = 16777215 * farz
|
// [5] = 16777215 * farz
|
||||||
const int old_fulltarget_w = s_Fulltarget_width;
|
const int old_fulltarget_w = Renderer::GetFullTargetWidth();
|
||||||
const int old_fulltarget_h = s_Fulltarget_height;
|
const int old_fulltarget_h = Renderer::GetFullTargetHeight();
|
||||||
|
|
||||||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||||
|
|
||||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
|
||||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
|
||||||
|
|
||||||
D3DVIEWPORT9 vp;
|
|
||||||
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride;
|
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)) * EFByScale) + Ystride;
|
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride;
|
||||||
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX());
|
||||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY());
|
||||||
if (Width < 0)
|
if (Width < 0)
|
||||||
{
|
{
|
||||||
X += Width;
|
X += Width;
|
||||||
|
@ -940,14 +742,14 @@ void UpdateViewport()
|
||||||
}
|
}
|
||||||
if (!IS_AMD)
|
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;
|
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;
|
sizeChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -955,16 +757,16 @@ void UpdateViewport()
|
||||||
{
|
{
|
||||||
D3DCAPS9 caps = D3D::GetCaps();
|
D3DCAPS9 caps = D3D::GetCaps();
|
||||||
// Make sure that the requested size is actually supported by the GFX driver
|
// 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
|
// 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
|
// 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;
|
X *= old_fulltarget_w / Renderer::GetFullTargetWidth();
|
||||||
Y *= old_fulltarget_h / s_Fulltarget_height;
|
Y *= old_fulltarget_h / Renderer::GetFullTargetHeight();
|
||||||
Width *= old_fulltarget_w / s_Fulltarget_width;
|
Width *= old_fulltarget_w / Renderer::GetFullTargetWidth();
|
||||||
Height *= old_fulltarget_h / s_Fulltarget_height;
|
Height *= old_fulltarget_h / Renderer::GetFullTargetHeight();
|
||||||
|
|
||||||
s_Fulltarget_width = old_fulltarget_w;
|
s_Fulltarget_width = old_fulltarget_w;
|
||||||
s_Fulltarget_height = old_fulltarget_h;
|
s_Fulltarget_height = old_fulltarget_h;
|
||||||
|
@ -981,6 +783,8 @@ void UpdateViewport()
|
||||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3DVIEWPORT9 vp;
|
||||||
vp.X = X;
|
vp.X = X;
|
||||||
vp.Y = Y;
|
vp.Y = Y;
|
||||||
vp.Width = Width;
|
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.
|
// 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)
|
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;
|
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
||||||
u32 xfbCount = 0;
|
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)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pCopiedToXFB(false);
|
g_VideoInitialize.pCopiedToXFB(false);
|
||||||
|
@ -1062,6 +884,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
if(g_ActiveConfig.bAnaglyphStereo)
|
if(g_ActiveConfig.bAnaglyphStereo)
|
||||||
{
|
{
|
||||||
static bool RightFrame = false;
|
static bool RightFrame = false;
|
||||||
|
@ -1213,16 +1036,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
if (s_bScreenshot)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
s_criticalScreenshot.Enter();
|
s_criticalScreenshot.Enter();
|
||||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
SaveScreenshot(s_sScreenshotName, dst_rect);
|
||||||
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.");
|
|
||||||
}
|
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
s_criticalScreenshot.Leave();
|
s_criticalScreenshot.Leave();
|
||||||
}
|
}
|
||||||
|
@ -1298,8 +1112,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
|
|
||||||
// Enable any configuration changes
|
// Enable any configuration changes
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
WindowResized = false;
|
const bool WindowResized = CheckForResize();
|
||||||
CheckForResize();
|
|
||||||
|
|
||||||
bool xfbchanged = false;
|
bool xfbchanged = false;
|
||||||
|
|
||||||
|
@ -1343,31 +1156,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
}
|
}
|
||||||
|
|
||||||
float SupersampleCoeficient = s_LastAA + 1;
|
float SupersampleCoeficient = s_LastAA + 1;
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
switch(s_LastEFBScale)
|
CalculateTargetSize(SupersampleCoeficient);
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
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.
|
// For testing zbuffer targets.
|
||||||
// Renderer::SetZBufferRender();
|
// Renderer::SetZBufferRender();
|
||||||
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
||||||
// GetTargetWidth(), GetTargetHeight());
|
// GetTargetWidth(), GetTargetHeight());
|
||||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
}
|
}
|
||||||
|
@ -1539,11 +1330,4 @@ void Renderer::SetInterlacingMode()
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save screenshot
|
|
||||||
void Renderer::SetScreenshot(const char *filename)
|
|
||||||
{
|
|
||||||
s_criticalScreenshot.Enter();
|
|
||||||
strcpy_s(s_sScreenshotName, filename);
|
|
||||||
s_bScreenshot = true;
|
|
||||||
s_criticalScreenshot.Leave();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
const float* const fConstAdd = colmat + 16; // fConstAdd is the last 4 floats of colmat
|
||||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||||
RECT sourcerect;
|
RECT sourcerect;
|
||||||
sourcerect.bottom = targetSource.bottom;
|
sourcerect.bottom = targetSource.bottom;
|
||||||
sourcerect.left = targetSource.left;
|
sourcerect.left = targetSource.left;
|
||||||
|
|
|
@ -372,11 +372,11 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
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);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
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)
|
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,
|
1.0f,
|
||||||
(float)Renderer::GetFullTargetWidth(),
|
(float)Renderer::GetFullTargetWidth(),
|
||||||
(float)Renderer::GetFullTargetHeight());
|
(float)Renderer::GetFullTargetHeight());
|
||||||
Renderer::ResetAPIState();
|
g_renderer->ResetAPIState();
|
||||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
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;
|
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);
|
LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false);
|
||||||
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
||||||
destTexture->GetSurfaceLevel(0,&Rendersurf);
|
destTexture->GetSurfaceLevel(0,&Rendersurf);
|
||||||
|
@ -536,7 +536,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
|
||||||
D3D::SetTexture(0,NULL);
|
D3D::SetTexture(0,NULL);
|
||||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
Rendersurf->Release();
|
Rendersurf->Release();
|
||||||
s_srcTexture->Release();
|
s_srcTexture->Release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ void VertexManager::vFlush()
|
||||||
{
|
{
|
||||||
if (usedtextures & (1 << i))
|
if (usedtextures & (1 << i))
|
||||||
{
|
{
|
||||||
Renderer::SetSamplerState(i & 3, i >> 2);
|
g_renderer->SetSamplerState(i & 3, i >> 2);
|
||||||
FourTexUnits &tex = bpmem.tex[i >> 2];
|
FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||||
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
|
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
|
||||||
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "Debugger/Debugger.h"
|
#include "Debugger/Debugger.h"
|
||||||
#endif // HAVE_WX
|
#endif // HAVE_WX
|
||||||
|
|
||||||
|
#include "MainBase.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "Fifo.h"
|
#include "Fifo.h"
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
#include "BPStructs.h"
|
#include "BPStructs.h"
|
||||||
#include "VertexManager.h"
|
#include "VertexManager.h"
|
||||||
|
#include "FramebufferManager.h"
|
||||||
#include "VertexLoaderManager.h"
|
#include "VertexLoaderManager.h"
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
|
@ -53,23 +55,6 @@
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
|
|
||||||
HINSTANCE g_hInstance = NULL;
|
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()
|
bool IsD3D()
|
||||||
{
|
{
|
||||||
|
@ -251,7 +236,7 @@ void Video_Prepare()
|
||||||
s_swapRequested = FALSE;
|
s_swapRequested = FALSE;
|
||||||
|
|
||||||
// internal interfaces
|
// internal interfaces
|
||||||
Renderer::Init();
|
g_renderer = new DX9::Renderer;
|
||||||
g_texture_cache = new DX9::TextureCache;
|
g_texture_cache = new DX9::TextureCache;
|
||||||
g_vertex_manager = new DX9::VertexManager;
|
g_vertex_manager = new DX9::VertexManager;
|
||||||
// VideoCommon
|
// VideoCommon
|
||||||
|
@ -291,7 +276,7 @@ void Shutdown()
|
||||||
VertexShaderCache::Shutdown();
|
VertexShaderCache::Shutdown();
|
||||||
delete g_vertex_manager;
|
delete g_vertex_manager;
|
||||||
delete g_texture_cache;
|
delete g_texture_cache;
|
||||||
Renderer::Shutdown();
|
delete g_renderer;
|
||||||
D3D::Shutdown();
|
D3D::Shutdown();
|
||||||
EmuWindow::Close();
|
EmuWindow::Close();
|
||||||
}
|
}
|
||||||
|
@ -306,192 +291,3 @@ void DoState(unsigned char **ptr, int mode)
|
||||||
PointerWrap p(ptr, mode);
|
PointerWrap p(ptr, mode);
|
||||||
VideoCommon_DoState(p);
|
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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,10 +20,8 @@
|
||||||
|
|
||||||
#include "PluginSpecs_Video.h"
|
#include "PluginSpecs_Video.h"
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
#include "MainBase.h"
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
extern volatile u32 s_swapRequested;
|
|
||||||
void VideoFifo_CheckEFBAccess();
|
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -733,10 +733,6 @@
|
||||||
<Filter
|
<Filter
|
||||||
Name="Render"
|
Name="Render"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath=".\Src\BPFunctions.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\FramebufferManager.cpp"
|
RelativePath=".\Src\FramebufferManager.cpp"
|
||||||
>
|
>
|
||||||
|
@ -765,6 +761,10 @@
|
||||||
RelativePath=".\Src\Render.cpp"
|
RelativePath=".\Src\Render.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\Render.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\TextureCache.cpp"
|
RelativePath=".\Src\TextureCache.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -211,7 +211,7 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc)
|
||||||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||||
// required.
|
// required.
|
||||||
|
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
// Resolve.
|
// Resolve.
|
||||||
|
@ -241,7 +241,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc)
|
||||||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||||
// required.
|
// required.
|
||||||
|
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||||
|
|
||||||
// Resolve.
|
// Resolve.
|
||||||
|
@ -269,7 +269,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||||
TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
TextureConverter::EncodeToRamYUYV(ResolveAndGetRenderTarget(sourceRc), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ CGprofile g_cgfProf;
|
||||||
|
|
||||||
RasterFont* s_pfont = NULL;
|
RasterFont* s_pfont = NULL;
|
||||||
|
|
||||||
static bool s_bLastFrameDumped = false;
|
|
||||||
#if defined _WIN32 || defined HAVE_AVCODEC
|
#if defined _WIN32 || defined HAVE_AVCODEC
|
||||||
static bool s_bAVIDumping = false;
|
static bool s_bAVIDumping = false;
|
||||||
#else
|
#else
|
||||||
|
@ -96,40 +95,10 @@ static int s_MSAACoverageSamples = 0;
|
||||||
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
|
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
|
||||||
static bool s_bHaveCoverageMSAA = false;
|
static bool s_bHaveCoverageMSAA = false;
|
||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
static int s_LastEFBScale;
|
|
||||||
|
|
||||||
static volatile bool s_bScreenshot = false;
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
static Common::Thread *scrshotThread = 0;
|
static Common::Thread *scrshotThread = 0;
|
||||||
#endif
|
#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;
|
int OSDChoice = 0 , OSDTime = 0, OSDInternalW = 0, OSDInternalH = 0;
|
||||||
|
|
||||||
|
@ -215,10 +184,12 @@ void VideoConfig::UpdateProjectionHack()
|
||||||
::UpdateProjectionHack(g_Config.iPhackvalue);
|
::UpdateProjectionHack(g_Config.iPhackvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init functions
|
namespace OGL
|
||||||
bool Renderer::Init()
|
{
|
||||||
|
|
||||||
|
// Init functions
|
||||||
|
Renderer::Renderer()
|
||||||
{
|
{
|
||||||
UpdateActiveConfig();
|
|
||||||
bool bSuccess = true;
|
bool bSuccess = true;
|
||||||
s_blendMode = 0;
|
s_blendMode = 0;
|
||||||
s_MSAACoverageSamples = 0;
|
s_MSAACoverageSamples = 0;
|
||||||
|
@ -226,20 +197,37 @@ bool Renderer::Init()
|
||||||
|
|
||||||
switch (g_ActiveConfig.iMultisampleMode)
|
switch (g_ActiveConfig.iMultisampleMode)
|
||||||
{
|
{
|
||||||
case MULTISAMPLE_OFF: s_MSAASamples = 1; break;
|
case MULTISAMPLE_OFF:
|
||||||
case MULTISAMPLE_2X: s_MSAASamples = 2; break;
|
s_MSAASamples = 1;
|
||||||
case MULTISAMPLE_4X: s_MSAASamples = 4; break;
|
break;
|
||||||
case MULTISAMPLE_8X: s_MSAASamples = 8; 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:
|
case MULTISAMPLE_CSAA_8X:
|
||||||
s_MSAASamples = 4; s_MSAACoverageSamples = 8; break;
|
s_MSAASamples = 4;
|
||||||
|
s_MSAACoverageSamples = 8;
|
||||||
|
break;
|
||||||
case MULTISAMPLE_CSAA_8XQ:
|
case MULTISAMPLE_CSAA_8XQ:
|
||||||
s_MSAASamples = 8; s_MSAACoverageSamples = 8; break;
|
s_MSAASamples = 8;
|
||||||
|
s_MSAACoverageSamples = 8;
|
||||||
|
break;
|
||||||
case MULTISAMPLE_CSAA_16X:
|
case MULTISAMPLE_CSAA_16X:
|
||||||
s_MSAASamples = 4; s_MSAACoverageSamples = 16; break;
|
s_MSAASamples = 4;
|
||||||
|
s_MSAACoverageSamples = 16;
|
||||||
|
break;
|
||||||
case MULTISAMPLE_CSAA_16XQ:
|
case MULTISAMPLE_CSAA_16XQ:
|
||||||
s_MSAASamples = 8; s_MSAACoverageSamples = 16; break;
|
s_MSAASamples = 8;
|
||||||
|
s_MSAACoverageSamples = 16;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
s_MSAASamples = 1;
|
s_MSAASamples = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined HAVE_CG && HAVE_CG
|
#if defined HAVE_CG && HAVE_CG
|
||||||
|
@ -255,7 +243,7 @@ bool Renderer::Init()
|
||||||
PanicAlert("Your OpenGL Driver seems to be not working.\n"
|
PanicAlert("Your OpenGL Driver seems to be not working.\n"
|
||||||
"Please make sure your drivers are up-to-date and\n"
|
"Please make sure your drivers are up-to-date and\n"
|
||||||
"that your video hardware is OpenGL 2.x compatible.");
|
"that your video hardware is OpenGL 2.x compatible.");
|
||||||
return false;
|
return; // TODO: fail
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(VIDEO, "Supported OpenGL Extensions:");
|
INFO_LOG(VIDEO, "Supported OpenGL Extensions:");
|
||||||
|
@ -280,7 +268,7 @@ bool Renderer::Init()
|
||||||
if (glewInit() != GLEW_OK)
|
if (glewInit() != GLEW_OK)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "glewInit() failed! Does your video card support OpenGL 2.x?");
|
ERROR_LOG(VIDEO, "glewInit() failed! Does your video card support OpenGL 2.x?");
|
||||||
return false;
|
return; // TODO: fail
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLEW_EXT_framebuffer_object)
|
if (!GLEW_EXT_framebuffer_object)
|
||||||
|
@ -311,7 +299,7 @@ bool Renderer::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
return false;
|
return; // TODO: fail
|
||||||
|
|
||||||
// Decide frambuffer size
|
// Decide frambuffer size
|
||||||
s_backbuffer_width = (int)OpenGL_GetBackbufferWidth();
|
s_backbuffer_width = (int)OpenGL_GetBackbufferWidth();
|
||||||
|
@ -366,27 +354,7 @@ bool Renderer::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||||
switch(s_LastEFBScale)
|
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
s_target_width = EFB_WIDTH * EFBxScale;
|
|
||||||
s_target_height = EFB_HEIGHT * EFByScale;
|
|
||||||
|
|
||||||
s_Fulltarget_width = s_target_width;
|
|
||||||
s_Fulltarget_height = s_target_height;
|
|
||||||
|
|
||||||
// Because of the fixed framebuffer size we need to disable the resolution
|
// Because of the fixed framebuffer size we need to disable the resolution
|
||||||
// options while running
|
// options while running
|
||||||
|
@ -411,13 +379,13 @@ bool Renderer::Init()
|
||||||
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE)
|
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "arbvp1 not supported");
|
ERROR_LOG(VIDEO, "arbvp1 not supported");
|
||||||
return false;
|
return; // TODO: fail
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE)
|
if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE)
|
||||||
{
|
{
|
||||||
ERROR_LOG(VIDEO, "arbfp1 not supported");
|
ERROR_LOG(VIDEO, "arbfp1 not supported");
|
||||||
return false;
|
return; // TODO: fail
|
||||||
}
|
}
|
||||||
|
|
||||||
g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||||
|
@ -505,10 +473,12 @@ bool Renderer::Init()
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
UpdateActiveConfig();
|
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;
|
g_Config.bRunning = false;
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
@ -539,49 +509,8 @@ void Renderer::Shutdown()
|
||||||
#endif
|
#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
|
// Create On-Screen-Messages
|
||||||
void Renderer::DrawDebugText()
|
void Renderer::DrawDebugInfo()
|
||||||
{
|
{
|
||||||
// Reset viewport for drawing text
|
// Reset viewport for drawing text
|
||||||
glViewport(0, 0, OpenGL_GetBackbufferWidth(), OpenGL_GetBackbufferHeight());
|
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, 21, 21, 0xDD000000);
|
||||||
Renderer::RenderText(debugtext_buffer, 20, 20, 0xFF00FFFF);
|
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<std::string> 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)
|
void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||||
{
|
{
|
||||||
int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
const int nBackbufferWidth = (int)OpenGL_GetBackbufferWidth();
|
||||||
int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
|
const int nBackbufferHeight = (int)OpenGL_GetBackbufferHeight();
|
||||||
|
|
||||||
glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f,
|
glColor4f(((color>>16) & 0xff)/255.0f, ((color>> 8) & 0xff)/255.0f,
|
||||||
((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f);
|
((color>> 0) & 0xff)/255.0f, ((color>>24) & 0xFF)/255.0f);
|
||||||
|
|
||||||
s_pfont->printMultilineText(text,
|
s_pfont->printMultilineText(text,
|
||||||
left * 2.0f / (float)nBackbufferWidth - 1,
|
left * 2.0f / (float)nBackbufferWidth - 1,
|
||||||
1 - top * 2.0f / (float)nBackbufferHeight,
|
1 - top * 2.0f / (float)nBackbufferHeight,
|
||||||
0, nBackbufferWidth, nBackbufferHeight);
|
0, nBackbufferWidth, nBackbufferHeight);
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,27 +610,6 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
return result;
|
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
|
// Function: This function handles the OpenGL glScissor() function
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
// 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
|
// therefore the width and height are (scissorBR + 1) - scissorTL
|
||||||
bool Renderer::SetScissorRect()
|
bool Renderer::SetScissorRect()
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
MathUtil::Rectangle<float> rc;
|
||||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
GetScissorRect(rc);
|
||||||
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
|
|
||||||
|
|
||||||
if (rc_left < 0) rc_left = 0;
|
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 > 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;
|
int temp = rc.right;
|
||||||
rc_right = rc_left;
|
rc.right = rc.left;
|
||||||
rc_left = temp;
|
rc.left = temp;
|
||||||
}
|
}
|
||||||
if (rc_top > rc_bottom)
|
if (rc.top > rc.bottom)
|
||||||
{
|
{
|
||||||
int temp = rc_bottom;
|
int temp = rc.bottom;
|
||||||
rc_bottom = rc_top;
|
rc.bottom = rc.top;
|
||||||
rc_top = temp;
|
rc.top = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the coordinates are good
|
// 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(
|
glScissor(
|
||||||
(int)(rc_left * EFBxScale), // x = 0 for example
|
(int)(rc.left * EFBxScale), // x = 0 for example
|
||||||
(int)((EFB_HEIGHT - rc_bottom) * EFByScale), // y = 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.right - rc.left)* EFBxScale), // width = 640 for example
|
||||||
(int)((rc_bottom - rc_top) * EFByScale) // height = 480 for example
|
(int)((rc.bottom - rc.top) * EFByScale) // height = 480 for example
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -962,7 +782,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
void UpdateViewport()
|
void Renderer::UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
// [0] = width/2
|
// [0] = width/2
|
||||||
|
@ -979,10 +799,10 @@ void UpdateViewport()
|
||||||
// int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
// int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||||
|
|
||||||
// Stretch picture with increased internal resolution
|
// Stretch picture with increased internal resolution
|
||||||
int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * EFBxScale);
|
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)) * EFByScale);
|
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] * EFBxScale);
|
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX());
|
||||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY());
|
||||||
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
||||||
double GLFar = xfregs.rawViewport[5] / 16777216.0f;
|
double GLFar = xfregs.rawViewport[5] / 16777216.0f;
|
||||||
if (Width < 0)
|
if (Width < 0)
|
||||||
|
@ -1131,8 +951,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DVSTARTPROFILE();
|
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
|
DVSTARTPROFILE();
|
||||||
TargetRectangle dst_rect;
|
TargetRectangle dst_rect;
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &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)
|
if (s_bScreenshot)
|
||||||
{
|
{
|
||||||
s_criticalScreenshot.Enter();
|
s_criticalScreenshot.Enter();
|
||||||
// Save screenshot
|
SaveScreenshot(s_sScreenshotName, dst_rect);
|
||||||
SaveRenderTarget(s_sScreenshotName.c_str(), dst_rect);
|
|
||||||
// Reset settings
|
// Reset settings
|
||||||
s_sScreenshotName = "";
|
s_sScreenshotName.clear();
|
||||||
s_bScreenshot = false;
|
s_bScreenshot = false;
|
||||||
s_criticalScreenshot.Leave();
|
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;
|
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;
|
delete g_framebuffer_manager;
|
||||||
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,
|
||||||
s_MSAASamples, s_MSAACoverageSamples);
|
s_MSAASamples, s_MSAACoverageSamples);
|
||||||
|
@ -1559,7 +1354,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||||
// For testing zbuffer targets.
|
// For testing zbuffer targets.
|
||||||
// Renderer::SetZBufferRender();
|
// Renderer::SetZBufferRender();
|
||||||
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
||||||
// GetTargetWidth(), GetTargetHeight());
|
// GetTargetWidth(), GetTargetHeight());
|
||||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||||
XFBWrited = false;
|
XFBWrited = false;
|
||||||
}
|
}
|
||||||
|
@ -1668,15 +1463,6 @@ void Renderer::SetInterlacingMode()
|
||||||
// TODO
|
// 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)
|
void Renderer::FlipImageData(u8 *data, int w, int h)
|
||||||
{
|
{
|
||||||
// Flip image upside down. Damn OpenGL.
|
// 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
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
THREAD_RETURN TakeScreenshot(void *pArgs)
|
THREAD_RETURN TakeScreenshot(void *pArgs)
|
||||||
{
|
{
|
||||||
|
@ -1739,7 +1527,10 @@ THREAD_RETURN TakeScreenshot(void *pArgs)
|
||||||
}
|
}
|
||||||
#endif
|
#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 W = back_rc.GetWidth();
|
||||||
u32 H = back_rc.GetHeight();
|
u32 H = back_rc.GetHeight();
|
||||||
|
@ -1769,7 +1560,7 @@ bool Renderer::SaveRenderTarget(const char *filename, TargetRectangle back_rc)
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrStrct *threadStruct = new ScrStrct;
|
ScrStrct *threadStruct = new ScrStrct;
|
||||||
threadStruct->filename = std::string(filename);
|
threadStruct->filename = filename;
|
||||||
threadStruct->img = a;
|
threadStruct->img = a;
|
||||||
threadStruct->H = H; threadStruct->W = W;
|
threadStruct->H = H; threadStruct->W = W;
|
||||||
|
|
||||||
|
@ -1782,9 +1573,11 @@ bool Renderer::SaveRenderTarget(const char *filename, TargetRectangle back_rc)
|
||||||
OSD::AddMessage("Saving Screenshot... ", 2000);
|
OSD::AddMessage("Saving Screenshot... ", 2000);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
bool result = SaveTGA(filename, W, H, data);
|
bool result = SaveTGA(filename.c_str(), W, H, data);
|
||||||
delete[] data;
|
delete[] data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -7,7 +7,6 @@ import sys
|
||||||
name = os.sep + "Plugin_VideoOGL"
|
name = os.sep + "Plugin_VideoOGL"
|
||||||
|
|
||||||
files = [
|
files = [
|
||||||
'BPFunctions.cpp',
|
|
||||||
'RasterFont.cpp',
|
'RasterFont.cpp',
|
||||||
'Render.cpp',
|
'Render.cpp',
|
||||||
'TextureCache.cpp',
|
'TextureCache.cpp',
|
||||||
|
|
|
@ -305,7 +305,7 @@ void TextureCache::TCacheEntry::FromRenderTarget(bool bFromZBuffer, bool bScaleB
|
||||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
glTexCoord2f((GLfloat)targetSource.left, (GLfloat)targetSource.bottom); glVertex2f(-1, 1);
|
||||||
|
|
|
@ -308,13 +308,13 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||||
cacheBytes = 64;
|
cacheBytes = 64;
|
||||||
|
|
||||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
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);
|
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
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)
|
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);
|
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||||
TextureCache::DisableStage(0);
|
TextureCache::DisableStage(0);
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
|
|
||||||
int srcFmtWidth = srcWidth / 2;
|
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
|
// switch to texture converter frame buffer
|
||||||
// attach destTexture as color destination
|
// attach destTexture as color destination
|
||||||
|
@ -462,7 +462,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
||||||
|
|
||||||
FramebufferManager::SetFramebuffer(0);
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
||||||
Renderer::RestoreAPIState();
|
g_renderer->RestoreAPIState();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,12 +198,12 @@ void VertexManager::vFlush()
|
||||||
{
|
{
|
||||||
// If host supports GL_ARB_blend_func_extended, we can do dst alpha in
|
// If host supports GL_ARB_blend_func_extended, we can do dst alpha in
|
||||||
// the same pass as regular rendering.
|
// the same pass as regular rendering.
|
||||||
Renderer::SetBlendMode(true);
|
g_renderer->SetBlendMode(true);
|
||||||
ps = PixelShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components);
|
ps = PixelShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Renderer::SetBlendMode(true);
|
g_renderer->SetBlendMode(true);
|
||||||
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ void VertexManager::vFlush()
|
||||||
|
|
||||||
Draw();
|
Draw();
|
||||||
// restore color mask
|
// restore color mask
|
||||||
Renderer::SetColorMask();
|
g_renderer->SetColorMask();
|
||||||
|
|
||||||
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -265,7 +265,7 @@ void VertexManager::vFlush()
|
||||||
tr.right = Renderer::GetTargetWidth();
|
tr.right = Renderer::GetTargetWidth();
|
||||||
tr.top = 0;
|
tr.top = 0;
|
||||||
tr.bottom = Renderer::GetTargetHeight();
|
tr.bottom = Renderer::GetTargetHeight();
|
||||||
Renderer::SaveRenderTarget(str, tr);
|
g_renderer->SaveScreenshot(str, tr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
g_Config.iSaveTargetId++;
|
g_Config.iSaveTargetId++;
|
||||||
|
|
|
@ -65,6 +65,7 @@ Make AA apply instantly during gameplay if possible
|
||||||
#include "Debugger/Debugger.h"
|
#include "Debugger/Debugger.h"
|
||||||
#endif // HAVE_WX
|
#endif // HAVE_WX
|
||||||
|
|
||||||
|
#include "MainBase.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "LookUpTables.h"
|
#include "LookUpTables.h"
|
||||||
#include "ImageWrite.h"
|
#include "ImageWrite.h"
|
||||||
|
@ -89,33 +90,16 @@ Make AA apply instantly during gameplay if possible
|
||||||
#include "OnScreenDisplay.h"
|
#include "OnScreenDisplay.h"
|
||||||
#include "Setup.h"
|
#include "Setup.h"
|
||||||
#include "DLCache.h"
|
#include "DLCache.h"
|
||||||
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
#include "VideoState.h"
|
#include "VideoState.h"
|
||||||
|
|
||||||
SVideoInitialize g_VideoInitialize;
|
|
||||||
PLUGIN_GLOBALS* globals = NULL;
|
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||||
|
|
||||||
static bool s_PluginInitialized = false;
|
|
||||||
|
|
||||||
volatile u32 s_swapRequested = FALSE;
|
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
static volatile u32 s_doStateRequested = FALSE;
|
static volatile u32 s_doStateRequested = FALSE;
|
||||||
#endif
|
#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()
|
bool IsD3D()
|
||||||
{
|
{
|
||||||
|
@ -236,11 +220,13 @@ void Initialize(void *init)
|
||||||
void Video_Prepare()
|
void Video_Prepare()
|
||||||
{
|
{
|
||||||
OpenGL_MakeCurrent();
|
OpenGL_MakeCurrent();
|
||||||
if (!Renderer::Init()) {
|
//if (!Renderer::Init()) {
|
||||||
g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
|
// 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");
|
// PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info");
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
g_renderer = new OGL::Renderer;
|
||||||
|
|
||||||
s_efbAccessRequested = FALSE;
|
s_efbAccessRequested = FALSE;
|
||||||
s_FifoShuttingDown = FALSE;
|
s_FifoShuttingDown = FALSE;
|
||||||
|
@ -295,7 +281,7 @@ void Shutdown()
|
||||||
delete g_vertex_manager;
|
delete g_vertex_manager;
|
||||||
delete g_texture_cache;
|
delete g_texture_cache;
|
||||||
OpcodeDecoder_Shutdown();
|
OpcodeDecoder_Shutdown();
|
||||||
Renderer::Shutdown();
|
delete g_renderer;
|
||||||
OpenGL_Shutdown();
|
OpenGL_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,195 +334,3 @@ void DoState(unsigned char **ptr, int mode)
|
||||||
#endif
|
#endif
|
||||||
check_DoState();
|
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();
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,10 +19,8 @@
|
||||||
#define _MAIN_H_
|
#define _MAIN_H_
|
||||||
|
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
#include "MainBase.h"
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
extern volatile u32 s_swapRequested;
|
|
||||||
void VideoFifo_CheckEFBAccess();
|
|
||||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
|
||||||
|
|
||||||
#endif // _MAIN_H_
|
#endif // _MAIN_H_
|
||||||
|
|
Loading…
Reference in New Issue