mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
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:
@ -675,14 +675,6 @@
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Decoder"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\BPFunctions.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Render"
|
||||
>
|
||||
@ -710,6 +702,10 @@
|
||||
RelativePath=".\Src\Render.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\Render.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\TextureCache.cpp"
|
||||
>
|
||||
|
@ -1,143 +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 "Debugger/Debugger.h"
|
||||
#include "TextureCache.h"
|
||||
#include "VertexManager.h"
|
||||
#include "VertexShaderManager.h"
|
||||
#include "VideoConfig.h"
|
||||
|
||||
bool textureChanged[8];
|
||||
const bool renderFog = false;
|
||||
|
||||
using namespace D3D;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
};
|
@ -192,7 +192,7 @@ void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, c
|
||||
return;
|
||||
}
|
||||
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
TargetRectangle targetRc = g_renderer->ConvertEFBRectangle(sourceRc);
|
||||
TextureConverter::EncodeToRamYUYV(GetEFBColorTexture(), targetRc, xfb_in_ram, fbWidth, fbHeight);
|
||||
}
|
||||
|
||||
|
@ -54,27 +54,6 @@
|
||||
|
||||
static int s_fps = 0;
|
||||
|
||||
static bool WindowResized;
|
||||
static int s_target_width;
|
||||
static int s_target_height;
|
||||
|
||||
static int s_Fulltarget_width;
|
||||
static int s_Fulltarget_height;
|
||||
|
||||
static int s_backbuffer_width;
|
||||
static int s_backbuffer_height;
|
||||
|
||||
static int s_XFB_width;
|
||||
static int s_XFB_height;
|
||||
|
||||
// ratio of backbuffer size and render area size
|
||||
static float xScale;
|
||||
static float yScale;
|
||||
|
||||
// Internal resolution scale (related to xScale/yScale for "Auto" scaling)
|
||||
static float EFBxScale;
|
||||
static float EFByScale;
|
||||
|
||||
static int s_recordWidth;
|
||||
static int s_recordHeight;
|
||||
|
||||
@ -83,18 +62,10 @@ static bool s_bAVIDumping;
|
||||
|
||||
static u32 s_blendMode;
|
||||
static u32 s_LastAA;
|
||||
static u32 s_LastEFBScale;
|
||||
static bool IS_AMD;
|
||||
static bool XFBWrited = false;
|
||||
|
||||
// used extern by other files. need to clean this up at some point.
|
||||
int frameCount;
|
||||
|
||||
static char *st;
|
||||
|
||||
static bool s_bScreenshot = false;
|
||||
static Common::CriticalSection s_criticalScreenshot;
|
||||
static char s_sScreenshotName[1024];
|
||||
static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL;
|
||||
|
||||
|
||||
@ -273,11 +244,14 @@ void TeardownDeviceObjects()
|
||||
TextureConverter::Shutdown();
|
||||
}
|
||||
|
||||
namespace DX9
|
||||
{
|
||||
|
||||
// Init functions
|
||||
bool Renderer::Init()
|
||||
Renderer::Renderer()
|
||||
{
|
||||
st = new char[32768];
|
||||
UpdateActiveConfig();
|
||||
|
||||
int fullScreenRes, x, y, w_temp, h_temp;
|
||||
s_blendMode = 0;
|
||||
// Multisample Anti-aliasing hasn't been implemented yet use supersamling instead
|
||||
@ -321,32 +295,10 @@ bool Renderer::Init()
|
||||
}
|
||||
|
||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
float SupersampleCoeficient = s_LastAA + 1;
|
||||
switch(s_LastEFBScale)
|
||||
{
|
||||
case 0:
|
||||
EFBxScale = xScale;
|
||||
EFByScale = yScale;
|
||||
break;
|
||||
case 1:
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
break;
|
||||
default:
|
||||
EFBxScale = g_ActiveConfig.iEFBScale - 1;
|
||||
EFByScale = EFBxScale;
|
||||
break;
|
||||
};
|
||||
|
||||
EFBxScale *= SupersampleCoeficient;
|
||||
EFByScale *= SupersampleCoeficient;
|
||||
|
||||
s_target_width = EFB_WIDTH * EFBxScale;
|
||||
s_target_height = EFB_HEIGHT * EFByScale;
|
||||
|
||||
s_Fulltarget_width = s_target_width;
|
||||
s_Fulltarget_height = s_target_height;
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
CalculateTargetSize(SupersampleCoeficient);
|
||||
|
||||
s_bLastFrameDumped = false;
|
||||
s_bAVIDumping = false;
|
||||
@ -384,10 +336,9 @@ bool Renderer::Init()
|
||||
D3D::BeginFrame();
|
||||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
||||
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
TeardownDeviceObjects();
|
||||
D3D::EndFrame();
|
||||
@ -398,142 +349,7 @@ void Renderer::Shutdown()
|
||||
{
|
||||
AVIDump::Stop();
|
||||
}
|
||||
delete [] st;
|
||||
}
|
||||
|
||||
// Return the rendering target width and height
|
||||
int Renderer::GetTargetWidth()
|
||||
{
|
||||
return s_target_width;
|
||||
}
|
||||
|
||||
int Renderer::GetTargetHeight()
|
||||
{
|
||||
return s_target_height;
|
||||
}
|
||||
|
||||
int Renderer::GetFullTargetWidth()
|
||||
{
|
||||
return s_Fulltarget_width;
|
||||
}
|
||||
|
||||
int Renderer::GetFullTargetHeight()
|
||||
{
|
||||
return s_Fulltarget_height;
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleX()
|
||||
{
|
||||
return EFBxScale;
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleY()
|
||||
{
|
||||
return EFByScale;
|
||||
}
|
||||
|
||||
float Renderer::GetXFBScaleX()
|
||||
{
|
||||
return xScale;
|
||||
}
|
||||
|
||||
float Renderer::GetXFBScaleY()
|
||||
{
|
||||
return yScale;
|
||||
}
|
||||
|
||||
// Create On-Screen-Messages
|
||||
void Renderer::DrawDebugText()
|
||||
{
|
||||
// OSD Menu messages
|
||||
if (g_ActiveConfig.bOSDHotKey)
|
||||
{
|
||||
if (OSDChoice > 0)
|
||||
{
|
||||
OSDTime = Common::Timer::GetTimeMs() + 3000;
|
||||
OSDChoice = -OSDChoice;
|
||||
}
|
||||
if ((u32)OSDTime > Common::Timer::GetTimeMs())
|
||||
{
|
||||
std::string T1 = "", T2 = "";
|
||||
std::vector<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);
|
||||
}
|
||||
}
|
||||
delete[] st;
|
||||
}
|
||||
|
||||
void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||
@ -553,6 +369,8 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||
{
|
||||
for (int y = 0; y < h; y++)
|
||||
@ -567,9 +385,12 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||
}
|
||||
}
|
||||
|
||||
namespace DX9
|
||||
{
|
||||
|
||||
// With D3D, we have to resize the backbuffer if the window changed
|
||||
// size.
|
||||
void CheckForResize()
|
||||
bool Renderer::CheckForResize()
|
||||
{
|
||||
while (EmuWindow::IsSizing())
|
||||
Sleep(10);
|
||||
@ -581,17 +402,18 @@ void CheckForResize()
|
||||
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
|
||||
int width = rcParentWindow.right - rcParentWindow.left;
|
||||
int height = rcParentWindow.bottom - rcParentWindow.top;
|
||||
if (width != s_backbuffer_width || height != s_backbuffer_height)
|
||||
if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight())
|
||||
MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||
}
|
||||
|
||||
RECT rcWindow;
|
||||
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
||||
int client_width = rcWindow.right - rcWindow.left;
|
||||
int client_height = rcWindow.bottom - rcWindow.top;
|
||||
|
||||
// Sanity check
|
||||
if ((client_width != s_backbuffer_width ||
|
||||
client_height != s_backbuffer_height) &&
|
||||
if ((client_width != Renderer::GetBackbufferWidth() ||
|
||||
client_height != Renderer::GetBackbufferHeight()) &&
|
||||
client_width >= 4 && client_height >= 4)
|
||||
{
|
||||
TeardownDeviceObjects();
|
||||
@ -601,47 +423,29 @@ void CheckForResize()
|
||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||
if(ScreenShootMEMSurface)
|
||||
ScreenShootMEMSurface->Release();
|
||||
D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
||||
WindowResized = true;
|
||||
}
|
||||
}
|
||||
D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(),
|
||||
D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL );
|
||||
|
||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
{
|
||||
if (!fbWidth || !fbHeight)
|
||||
return;
|
||||
VideoFifo_CheckEFBAccess();
|
||||
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
|
||||
XFBWrited = true;
|
||||
// XXX: Without the VI, how would we know what kind of field this is? So
|
||||
// just use progressive.
|
||||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
FramebufferManager::CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Renderer::Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc);
|
||||
Common::AtomicStoreRelease(s_swapRequested, FALSE);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Renderer::SetScissorRect()
|
||||
{
|
||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
||||
RECT rc;
|
||||
rc.left = (int)((float)bpmem.scissorTL.x - xoff - 342);
|
||||
rc.top = (int)((float)bpmem.scissorTL.y - yoff - 342);
|
||||
rc.right = (int)((float)bpmem.scissorBR.x - xoff - 341);
|
||||
rc.bottom = (int)((float)bpmem.scissorBR.y - yoff - 341);
|
||||
TargetRectangle rc;
|
||||
GetScissorRect(rc);
|
||||
|
||||
if (rc.left < 0) rc.left = 0;
|
||||
if (rc.right < 0) rc.right = 0;
|
||||
|
||||
if (rc.left > EFB_WIDTH) rc.left = EFB_WIDTH;
|
||||
if (rc.right > EFB_WIDTH) rc.right = EFB_WIDTH;
|
||||
|
||||
if (rc.top < 0) rc.top = 0;
|
||||
if (rc.bottom < 0) rc.bottom = 0;
|
||||
|
||||
if (rc.top > EFB_HEIGHT) rc.top = EFB_HEIGHT;
|
||||
if (rc.bottom > EFB_HEIGHT) rc.bottom = EFB_HEIGHT;
|
||||
|
||||
@ -669,7 +473,7 @@ bool Renderer::SetScissorRect()
|
||||
// Check that the coordinates are good
|
||||
if (rc.right != rc.left && rc.bottom != rc.top)
|
||||
{
|
||||
D3D::dev->SetScissorRect(&rc);
|
||||
D3D::dev->SetScissorRect(rc.AsRECT());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -679,7 +483,7 @@ bool Renderer::SetScissorRect()
|
||||
rc.top = Ystride;
|
||||
rc.right = Xstride + s_target_width;
|
||||
rc.bottom = Ystride + s_target_height;
|
||||
D3D::dev->SetScissorRect(&rc);
|
||||
D3D::dev->SetScissorRect(rc.AsRECT());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -890,7 +694,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
}
|
||||
|
||||
// Called from VertexShaderManager
|
||||
void UpdateViewport()
|
||||
void Renderer::UpdateViewport()
|
||||
{
|
||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||
// [0] = width/2
|
||||
@ -899,22 +703,20 @@ void UpdateViewport()
|
||||
// [3] = xorig + width/2 + 342
|
||||
// [4] = yorig + height/2 + 342
|
||||
// [5] = 16777215 * farz
|
||||
const int old_fulltarget_w = s_Fulltarget_width;
|
||||
const int old_fulltarget_h = s_Fulltarget_height;
|
||||
const int old_fulltarget_w = Renderer::GetFullTargetWidth();
|
||||
const int old_fulltarget_h = Renderer::GetFullTargetHeight();
|
||||
|
||||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
|
||||
D3DVIEWPORT9 vp;
|
||||
int Xstride = (Renderer::GetFullTargetWidth() - Renderer::GetTargetWidth()) / 2;
|
||||
int Ystride = (Renderer::GetFullTargetHeight() - Renderer::GetTargetHeight()) / 2;
|
||||
|
||||
// Stretch picture with increased internal resolution
|
||||
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride;
|
||||
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * EFByScale) + Ystride;
|
||||
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
||||
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * Renderer::GetTargetScaleX()) + Xstride;
|
||||
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * Renderer::GetTargetScaleY()) + Ystride;
|
||||
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * Renderer::GetTargetScaleX());
|
||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * Renderer::GetTargetScaleY());
|
||||
if (Width < 0)
|
||||
{
|
||||
X += Width;
|
||||
@ -940,14 +742,14 @@ void UpdateViewport()
|
||||
}
|
||||
if (!IS_AMD)
|
||||
{
|
||||
if(X + Width > s_Fulltarget_width)
|
||||
if(X + Width > Renderer::GetFullTargetWidth())
|
||||
{
|
||||
s_Fulltarget_width += (X + Width - s_Fulltarget_width) * 2;
|
||||
s_Fulltarget_width += (X + Width - Renderer::GetFullTargetWidth()) * 2;
|
||||
sizeChanged = true;
|
||||
}
|
||||
if(Y + Height > s_Fulltarget_height)
|
||||
if(Y + Height > Renderer::GetFullTargetHeight())
|
||||
{
|
||||
s_Fulltarget_height += (Y + Height - s_Fulltarget_height) * 2;
|
||||
s_Fulltarget_height += (Y + Height - Renderer::GetFullTargetHeight()) * 2;
|
||||
sizeChanged = true;
|
||||
}
|
||||
}
|
||||
@ -955,16 +757,16 @@ void UpdateViewport()
|
||||
{
|
||||
D3DCAPS9 caps = D3D::GetCaps();
|
||||
// Make sure that the requested size is actually supported by the GFX driver
|
||||
if (s_Fulltarget_width > caps.MaxTextureWidth || s_Fulltarget_height > caps.MaxTextureHeight)
|
||||
if (Renderer::GetFullTargetWidth() > caps.MaxTextureWidth || Renderer::GetFullTargetHeight() > caps.MaxTextureHeight)
|
||||
{
|
||||
// Skip EFB recreation and viewport setting. Most likely causes glitches in this case, but prevents crashes at least
|
||||
ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D9. Requested EFB size is %dx%d, keeping the %dx%d EFB now\n", s_Fulltarget_width, s_Fulltarget_height, old_fulltarget_w, old_fulltarget_h);
|
||||
ERROR_LOG(VIDEO, "Tried to set a viewport which is too wide to emulate with Direct3D9. Requested EFB size is %dx%d, keeping the %dx%d EFB now\n", Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), old_fulltarget_w, old_fulltarget_h);
|
||||
|
||||
// Fix the viewport to fit to the old EFB size, TODO: Check this for off-by-one errors
|
||||
X *= old_fulltarget_w / s_Fulltarget_width;
|
||||
Y *= old_fulltarget_h / s_Fulltarget_height;
|
||||
Width *= old_fulltarget_w / s_Fulltarget_width;
|
||||
Height *= old_fulltarget_h / s_Fulltarget_height;
|
||||
X *= old_fulltarget_w / Renderer::GetFullTargetWidth();
|
||||
Y *= old_fulltarget_h / Renderer::GetFullTargetHeight();
|
||||
Width *= old_fulltarget_w / Renderer::GetFullTargetWidth();
|
||||
Height *= old_fulltarget_h / Renderer::GetFullTargetHeight();
|
||||
|
||||
s_Fulltarget_width = old_fulltarget_w;
|
||||
s_Fulltarget_height = old_fulltarget_h;
|
||||
@ -981,6 +783,8 @@ void UpdateViewport()
|
||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||
}
|
||||
}
|
||||
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = X;
|
||||
vp.Y = Y;
|
||||
vp.Width = Width;
|
||||
@ -1040,6 +844,24 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &dst_rect)
|
||||
{
|
||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Error dumping surface data.");
|
||||
return false;
|
||||
}
|
||||
hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT());
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Error saving screen.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function has the final picture. We adjust the aspect ratio here.
|
||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
|
||||
{
|
||||
@ -1054,7 +876,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
|
||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
||||
u32 xfbCount = 0;
|
||||
const XFBSourceBase *const *xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
g_VideoInitialize.pCopiedToXFB(false);
|
||||
@ -1062,6 +884,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
}
|
||||
|
||||
ResetAPIState();
|
||||
|
||||
if(g_ActiveConfig.bAnaglyphStereo)
|
||||
{
|
||||
static bool RightFrame = false;
|
||||
@ -1113,7 +936,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
int Width = dst_rect.right - dst_rect.left;
|
||||
int Height = dst_rect.bottom - dst_rect.top;
|
||||
|
||||
// Sanity check
|
||||
// Sanity check
|
||||
if (X < 0) X = 0;
|
||||
if (Y < 0) Y = 0;
|
||||
if (X > s_backbuffer_width) X = s_backbuffer_width;
|
||||
@ -1213,16 +1036,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
if (s_bScreenshot)
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Error dumping surface data.");
|
||||
}
|
||||
hr = PD3DXSaveSurfaceToFileA(s_sScreenshotName, D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT());
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Error saving screen.");
|
||||
}
|
||||
SaveScreenshot(s_sScreenshotName, dst_rect);
|
||||
s_bScreenshot = false;
|
||||
s_criticalScreenshot.Leave();
|
||||
}
|
||||
@ -1298,8 +1112,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
|
||||
// Enable any configuration changes
|
||||
UpdateActiveConfig();
|
||||
WindowResized = false;
|
||||
CheckForResize();
|
||||
const bool WindowResized = CheckForResize();
|
||||
|
||||
bool xfbchanged = false;
|
||||
|
||||
@ -1343,31 +1156,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
}
|
||||
|
||||
float SupersampleCoeficient = s_LastAA + 1;
|
||||
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
switch(s_LastEFBScale)
|
||||
{
|
||||
case 0:
|
||||
EFBxScale = xScale;
|
||||
EFByScale = yScale;
|
||||
break;
|
||||
case 1:
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
break;
|
||||
default:
|
||||
EFBxScale = g_ActiveConfig.iEFBScale - 1;
|
||||
EFByScale = EFBxScale;
|
||||
break;
|
||||
};
|
||||
|
||||
EFBxScale *= SupersampleCoeficient;
|
||||
EFByScale *= SupersampleCoeficient;
|
||||
|
||||
s_target_width = EFB_WIDTH * EFBxScale;
|
||||
s_target_height = EFB_HEIGHT * EFByScale;
|
||||
|
||||
s_Fulltarget_width = s_target_width;
|
||||
s_Fulltarget_height = s_target_height;
|
||||
CalculateTargetSize(SupersampleCoeficient);
|
||||
|
||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||
@ -1416,7 +1207,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
||||
// For testing zbuffer targets.
|
||||
// Renderer::SetZBufferRender();
|
||||
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
|
||||
// GetTargetWidth(), GetTargetHeight());
|
||||
// GetTargetWidth(), GetTargetHeight());
|
||||
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
|
||||
XFBWrited = false;
|
||||
}
|
||||
@ -1539,11 +1330,4 @@ void Renderer::SetInterlacingMode()
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Save screenshot
|
||||
void Renderer::SetScreenshot(const char *filename)
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
strcpy_s(s_sScreenshotName, filename);
|
||||
s_bScreenshot = true;
|
||||
s_criticalScreenshot.Leave();
|
||||
}
|
||||
|
49
Source/Plugins/Plugin_VideoDX9/Src/Render.h
Normal file
49
Source/Plugins/Plugin_VideoDX9/Src/Render.h
Normal file
@ -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
|
||||
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
|
||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
||||
TargetRectangle targetSource = g_renderer->ConvertEFBRectangle(source_rect);
|
||||
RECT sourcerect;
|
||||
sourcerect.bottom = targetSource.bottom;
|
||||
sourcerect.left = targetSource.left;
|
||||
|
@ -372,11 +372,11 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
||||
cacheBytes = 64;
|
||||
|
||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||
Renderer::ResetAPIState();
|
||||
g_renderer->ResetAPIState();
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
|
||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||
Renderer::RestoreAPIState();
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||
@ -459,11 +459,11 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
|
||||
1.0f,
|
||||
(float)Renderer::GetFullTargetWidth(),
|
||||
(float)Renderer::GetFullTargetHeight());
|
||||
Renderer::ResetAPIState();
|
||||
g_renderer->ResetAPIState();
|
||||
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
|
||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||
Renderer::RestoreAPIState();
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
|
||||
|
||||
@ -479,7 +479,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
|
||||
|
||||
int srcFmtWidth = srcWidth / 2;
|
||||
|
||||
Renderer::ResetAPIState(); // reset any game specific settings
|
||||
g_renderer->ResetAPIState(); // reset any game specific settings
|
||||
LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false);
|
||||
LPDIRECT3DSURFACE9 Rendersurf = NULL;
|
||||
destTexture->GetSurfaceLevel(0,&Rendersurf);
|
||||
@ -536,7 +536,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
|
||||
D3D::SetTexture(0,NULL);
|
||||
D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface());
|
||||
Renderer::RestoreAPIState();
|
||||
g_renderer->RestoreAPIState();
|
||||
Rendersurf->Release();
|
||||
s_srcTexture->Release();
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ void VertexManager::vFlush()
|
||||
{
|
||||
if (usedtextures & (1 << i))
|
||||
{
|
||||
Renderer::SetSamplerState(i & 3, i >> 2);
|
||||
g_renderer->SetSamplerState(i & 3, i >> 2);
|
||||
FourTexUnits &tex = bpmem.tex[i >> 2];
|
||||
TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i,
|
||||
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "Debugger/Debugger.h"
|
||||
#endif // HAVE_WX
|
||||
|
||||
#include "MainBase.h"
|
||||
#include "main.h"
|
||||
#include "VideoConfig.h"
|
||||
#include "Fifo.h"
|
||||
@ -36,6 +37,7 @@
|
||||
#include "TextureCache.h"
|
||||
#include "BPStructs.h"
|
||||
#include "VertexManager.h"
|
||||
#include "FramebufferManager.h"
|
||||
#include "VertexLoaderManager.h"
|
||||
#include "VertexShaderManager.h"
|
||||
#include "PixelShaderManager.h"
|
||||
@ -53,23 +55,6 @@
|
||||
#include "DLCache.h"
|
||||
|
||||
HINSTANCE g_hInstance = NULL;
|
||||
SVideoInitialize g_VideoInitialize;
|
||||
PLUGIN_GLOBALS* globals = NULL;
|
||||
static bool s_PluginInitialized = false;
|
||||
|
||||
volatile u32 s_swapRequested = FALSE;
|
||||
static u32 s_efbAccessRequested = FALSE;
|
||||
static volatile u32 s_FifoShuttingDown = FALSE;
|
||||
|
||||
static volatile struct
|
||||
{
|
||||
u32 xfbAddr;
|
||||
FieldType field;
|
||||
u32 fbWidth;
|
||||
u32 fbHeight;
|
||||
} s_beginFieldArgs;
|
||||
|
||||
static volatile EFBAccessType s_AccessEFBType;
|
||||
|
||||
bool IsD3D()
|
||||
{
|
||||
@ -251,7 +236,7 @@ void Video_Prepare()
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
// internal interfaces
|
||||
Renderer::Init();
|
||||
g_renderer = new DX9::Renderer;
|
||||
g_texture_cache = new DX9::TextureCache;
|
||||
g_vertex_manager = new DX9::VertexManager;
|
||||
// VideoCommon
|
||||
@ -291,7 +276,7 @@ void Shutdown()
|
||||
VertexShaderCache::Shutdown();
|
||||
delete g_vertex_manager;
|
||||
delete g_texture_cache;
|
||||
Renderer::Shutdown();
|
||||
delete g_renderer;
|
||||
D3D::Shutdown();
|
||||
EmuWindow::Close();
|
||||
}
|
||||
@ -306,192 +291,3 @@ void DoState(unsigned char **ptr, int mode)
|
||||
PointerWrap p(ptr, mode);
|
||||
VideoCommon_DoState(p);
|
||||
}
|
||||
|
||||
void EmuStateChange(PLUGIN_EMUSTATE newState)
|
||||
{
|
||||
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
||||
}
|
||||
|
||||
// Enter and exit the video loop
|
||||
void Video_EnterLoop()
|
||||
{
|
||||
Fifo_EnterLoop(g_VideoInitialize);
|
||||
}
|
||||
|
||||
void Video_ExitLoop()
|
||||
{
|
||||
Fifo_ExitLoop();
|
||||
s_FifoShuttingDown = TRUE;
|
||||
}
|
||||
|
||||
void Video_SetRendering(bool bEnabled)
|
||||
{
|
||||
Fifo_SetRendering(bEnabled);
|
||||
}
|
||||
|
||||
// Run from the graphics thread (from Fifo.cpp)
|
||||
void VideoFifo_CheckSwapRequest()
|
||||
{
|
||||
if(g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
if (Common::AtomicLoadAcquire(s_swapRequested))
|
||||
{
|
||||
EFBRectangle rc;
|
||||
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc);
|
||||
Common::AtomicStoreRelease(s_swapRequested, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||
{
|
||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||
}
|
||||
|
||||
// Run from the graphics thread (from Fifo.cpp)
|
||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
if (g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
if(Common::AtomicLoadAcquire(s_swapRequested))
|
||||
{
|
||||
u32 aLower = xfbAddr;
|
||||
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
|
||||
u32 bLower = s_beginFieldArgs.xfbAddr;
|
||||
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
|
||||
|
||||
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
|
||||
VideoFifo_CheckSwapRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run from the CPU thread (from VideoInterface.cpp)
|
||||
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
if (!g_VideoInitialize.bOnThread)
|
||||
VideoFifo_CheckSwapRequest();
|
||||
s_beginFieldArgs.xfbAddr = xfbAddr;
|
||||
s_beginFieldArgs.field = field;
|
||||
s_beginFieldArgs.fbWidth = fbWidth;
|
||||
s_beginFieldArgs.fbHeight = fbHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Run from the CPU thread (from VideoInterface.cpp)
|
||||
void Video_EndField()
|
||||
{
|
||||
if (s_PluginInitialized)
|
||||
{
|
||||
Common::AtomicStoreRelease(s_swapRequested, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void Video_AddMessage(const char* pstr, u32 milliseconds)
|
||||
{
|
||||
OSD::AddMessage(pstr, milliseconds);
|
||||
}
|
||||
|
||||
// Screenshot
|
||||
void Video_Screenshot(const char *_szFilename)
|
||||
{
|
||||
Renderer::SetScreenshot(_szFilename);
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
EFBAccessType type;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u32 Data;
|
||||
} s_accessEFBArgs;
|
||||
|
||||
static u32 s_AccessEFBResult = 0;
|
||||
|
||||
void VideoFifo_CheckEFBAccess()
|
||||
{
|
||||
if (Common::AtomicLoadAcquire(s_efbAccessRequested))
|
||||
{
|
||||
s_AccessEFBResult = Renderer::AccessEFB(s_accessEFBArgs.type, s_accessEFBArgs.x, s_accessEFBArgs.y, s_accessEFBArgs.Data);
|
||||
|
||||
Common::AtomicStoreRelease(s_efbAccessRequested, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
|
||||
{
|
||||
if (s_PluginInitialized)
|
||||
{
|
||||
s_accessEFBArgs.type = type;
|
||||
s_accessEFBArgs.x = x;
|
||||
s_accessEFBArgs.y = y;
|
||||
s_accessEFBArgs.Data = InputData;
|
||||
|
||||
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
|
||||
|
||||
if (g_VideoInitialize.bOnThread)
|
||||
{
|
||||
while (Common::AtomicLoadAcquire(s_efbAccessRequested) && !s_FifoShuttingDown)
|
||||
//Common::SleepCurrentThread(1);
|
||||
Common::YieldCPU();
|
||||
}
|
||||
else
|
||||
VideoFifo_CheckEFBAccess();
|
||||
|
||||
return s_AccessEFBResult;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VideoFifo_CheckAsyncRequest() {
|
||||
VideoFifo_CheckSwapRequest();
|
||||
VideoFifo_CheckEFBAccess();
|
||||
}
|
||||
|
||||
void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address)
|
||||
{
|
||||
CommandProcessor::Read16(_rReturnValue, _Address);
|
||||
}
|
||||
|
||||
void Video_CommandProcessorWrite16(const u16 _Data, const u32 _Address)
|
||||
{
|
||||
CommandProcessor::Write16(_Data, _Address);
|
||||
}
|
||||
|
||||
void Video_PixelEngineRead16(u16& _rReturnValue, const u32 _Address)
|
||||
{
|
||||
PixelEngine::Read16(_rReturnValue, _Address);
|
||||
}
|
||||
|
||||
void Video_PixelEngineWrite16(const u16 _Data, const u32 _Address)
|
||||
{
|
||||
PixelEngine::Write16(_Data, _Address);
|
||||
}
|
||||
|
||||
void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
|
||||
{
|
||||
PixelEngine::Write32(_Data, _Address);
|
||||
}
|
||||
|
||||
void Video_GatherPipeBursted(void)
|
||||
{
|
||||
CommandProcessor::GatherPipeBursted();
|
||||
}
|
||||
|
||||
void Video_WaitForFrameFinish(void)
|
||||
{
|
||||
CommandProcessor::WaitForFrameFinish();
|
||||
}
|
||||
|
||||
bool Video_IsFifoBusy(void)
|
||||
{
|
||||
return CommandProcessor::isFifoBusy;
|
||||
}
|
||||
|
||||
void Video_AbortFrame(void)
|
||||
{
|
||||
CommandProcessor::AbortFrame();
|
||||
}
|
||||
|
@ -20,10 +20,8 @@
|
||||
|
||||
#include "PluginSpecs_Video.h"
|
||||
#include "Render.h"
|
||||
#include "MainBase.h"
|
||||
|
||||
extern SVideoInitialize g_VideoInitialize;
|
||||
extern volatile u32 s_swapRequested;
|
||||
void VideoFifo_CheckEFBAccess();
|
||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user