Added EFB Scale option to the OpenGL plug-in.
Renamed EFB Scale to Internal Resolution. Removed Auto Scale option (it is now always on). Added on-the-fly changing of the Internal Resolution in the OpenGL and Direct3D9 plug-ins. Further consolidated the code in the video plug-ins. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6240 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ce1057f17d
commit
719521eeeb
|
@ -59,9 +59,6 @@ public:
|
|||
static void SetLineWidth();
|
||||
static void SetSamplerState(int stage,int texindex);
|
||||
static void SetInterlacingMode();
|
||||
// Live resolution change
|
||||
static bool Allow2x();
|
||||
static bool AllowCustom();
|
||||
|
||||
// Render target management
|
||||
static int GetFrameBufferWidth();
|
||||
|
|
|
@ -48,14 +48,11 @@ void VideoConfig::Load(const char *ini_file)
|
|||
iniFile.Load(ini_file);
|
||||
|
||||
iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware
|
||||
iniFile.Get("Settings", "StretchToFit", &bNativeResolution, true);
|
||||
iniFile.Get("Settings", "2xResolution", &b2xResolution, false);
|
||||
iniFile.Get("Settings", "wideScreenHack", &bWidescreenHack, false);
|
||||
iniFile.Get("Settings", "AspectRatio", &iAspectRatio, (int)ASPECT_AUTO);
|
||||
iniFile.Get("Settings", "Crop", &bCrop, false);
|
||||
iniFile.Get("Settings", "UseXFB", &bUseXFB, 0);
|
||||
iniFile.Get("Settings", "UseRealXFB", &bUseRealXFB, 0);
|
||||
iniFile.Get("Settings", "AutoScale", &bAutoScale, true);
|
||||
iniFile.Get("Settings", "UseNativeMips", &bUseNativeMips, true);
|
||||
|
||||
iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings
|
||||
|
@ -165,14 +162,11 @@ void VideoConfig::Save(const char *ini_file)
|
|||
IniFile iniFile;
|
||||
iniFile.Load(ini_file);
|
||||
iniFile.Set("Hardware", "VSync", bVSync);
|
||||
iniFile.Set("Settings", "StretchToFit", bNativeResolution);
|
||||
iniFile.Set("Settings", "2xResolution", b2xResolution);
|
||||
iniFile.Set("Settings", "AspectRatio", iAspectRatio);
|
||||
iniFile.Set("Settings", "Crop", bCrop);
|
||||
iniFile.Set("Settings", "wideScreenHack", bWidescreenHack);
|
||||
iniFile.Set("Settings", "UseXFB", bUseXFB);
|
||||
iniFile.Set("Settings", "UseRealXFB", bUseRealXFB);
|
||||
iniFile.Set("Settings", "AutoScale", bAutoScale);
|
||||
iniFile.Set("Settings", "UseNativeMips", bUseNativeMips);
|
||||
|
||||
iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache);
|
||||
|
|
|
@ -69,13 +69,12 @@ struct VideoConfig
|
|||
// General
|
||||
bool bVSync;
|
||||
|
||||
bool bNativeResolution, b2xResolution, bRunning; // Should possibly be augmented with 2x, 4x native.
|
||||
bool bRunning;
|
||||
bool bWidescreenHack;
|
||||
int iAspectRatio;
|
||||
bool bCrop; // Aspect ratio controls.
|
||||
bool bUseXFB;
|
||||
bool bUseRealXFB;
|
||||
bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly.
|
||||
bool bUseNativeMips;
|
||||
|
||||
// OpenCL
|
||||
|
|
|
@ -924,17 +924,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||
|
||||
if (!g_ActiveConfig.bAutoScale)
|
||||
{
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
float vScale = (float)fbHeight / (float)s_backbuffer_height;
|
||||
float hScale = (float)fbWidth / (float)s_backbuffer_width;
|
||||
|
||||
drawRc.top *= vScale;
|
||||
drawRc.bottom *= vScale;
|
||||
drawRc.left *= hScale;
|
||||
drawRc.right *= hScale;
|
||||
}
|
||||
// The following code disables auto stretch. Kept for reference.
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
//float vScale = (float)fbHeight / (float)s_backbuffer_height;
|
||||
//float hScale = (float)fbWidth / (float)s_backbuffer_width;
|
||||
//drawRc.top *= vScale;
|
||||
//drawRc.bottom *= vScale;
|
||||
//drawRc.left *= hScale;
|
||||
//drawRc.right *= hScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -210,9 +210,9 @@ void GFXConfigDialogDX::CreateGUIControls()
|
|||
arrayStringFor_MSAAModeCB.Add(wxString::FromAscii(adapter.aa_levels[i].name));
|
||||
}
|
||||
m_MSAAModeCB = new wxChoice( m_PageDirect3D, ID_ANTIALIASMODE, wxPoint( -1,-1 ), wxDefaultSize, arrayStringFor_MSAAModeCB, 0);
|
||||
m_EFBScaleText = new wxStaticText( m_PageDirect3D, wxID_ANY, wxT("EFB scale:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_EFBScaleText = new wxStaticText( m_PageDirect3D, wxID_ANY, wxT("Internal Resolution:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_EFBScaleText->Wrap( -1 );
|
||||
wxString m_EFBScaleModeChoices[] = { wxT("Auto (fractional)"), wxT("Auto (integral)"), wxT("1x"), wxT("2x"), wxT("3x") };
|
||||
wxString m_EFBScaleModeChoices[] = { wxT("Auto (fractional)"), wxT("Auto (integral)"), wxT("Native"), wxT("2x"), wxT("3x") };
|
||||
int m_EFBScaleModeNChoices = sizeof( m_EFBScaleModeChoices ) / sizeof( wxString );
|
||||
m_EFBScaleMode = new wxChoice( m_PageDirect3D, ID_EFBSCALEMODE, wxDefaultPosition, wxDefaultSize, m_EFBScaleModeNChoices, m_EFBScaleModeChoices, 0 );
|
||||
|
||||
|
|
|
@ -145,8 +145,8 @@ void OSDMenu(WPARAM wParam)
|
|||
case '3':
|
||||
OSDChoice = 1;
|
||||
// Toggle native resolution
|
||||
OSDInternalW = D3D::GetBackBufferWidth();
|
||||
OSDInternalH = D3D::GetBackBufferHeight();
|
||||
g_Config.iEFBScale = g_Config.iEFBScale + 1;
|
||||
if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
|
||||
break;
|
||||
case '4':
|
||||
OSDChoice = 2;
|
||||
|
|
|
@ -276,7 +276,7 @@ void PixelShaderCache::Shutdown()
|
|||
bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
{
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlpha);
|
||||
GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
|
|
|
@ -308,7 +308,8 @@ bool Renderer::Init()
|
|||
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
xScale = yScale = 1.0f;
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -438,21 +439,10 @@ 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
|
||||
// OSD Menu messages
|
||||
if (g_ActiveConfig.bOSDHotKey)
|
||||
{
|
||||
if (OSDChoice > 0)
|
||||
|
@ -465,7 +455,26 @@ void Renderer::DrawDebugText()
|
|||
std::string T1 = "", T2 = "";
|
||||
std::vector<std::string> T0;
|
||||
|
||||
std::string OSDM1 = StringFromFormat("%i x %i", OSDInternalW, OSDInternalH);
|
||||
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)
|
||||
{
|
||||
|
@ -531,9 +540,9 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
|||
|
||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
{
|
||||
TargetRectangle result;
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
TargetRectangle result;
|
||||
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
||||
result.top = (int)(rc.top * EFByScale) + Ystride;
|
||||
result.right = (int)(rc.right * EFBxScale) + Xstride;
|
||||
|
@ -654,6 +663,7 @@ bool Renderer::SetScissorRect()
|
|||
rc.right = (int)(rc.right * EFBxScale) + Xstride;
|
||||
rc.bottom = (int)(rc.bottom * EFByScale) + Ystride;
|
||||
|
||||
// Check that the coordinates are good
|
||||
if (rc.right != rc.left && rc.bottom != rc.top)
|
||||
{
|
||||
D3D::dev->SetScissorRect(&rc);
|
||||
|
@ -727,7 +737,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
efbPixelRc.right = x + 1;
|
||||
efbPixelRc.bottom = y + 1;
|
||||
|
||||
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
||||
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
|
||||
|
||||
u32 z = 0;
|
||||
float val = 0.0f;
|
||||
|
@ -897,19 +907,16 @@ void UpdateViewport()
|
|||
int scissorXOff = bpmem.scissorOffset.x * 2;
|
||||
int scissorYOff = bpmem.scissorOffset.y * 2;
|
||||
|
||||
float MValueX = Renderer::GetTargetScaleX();
|
||||
float MValueY = Renderer::GetTargetScaleY();
|
||||
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
|
||||
D3DVIEWPORT9 vp;
|
||||
|
||||
// Stretch picture with increased internal resolution
|
||||
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * MValueX) + Xstride;
|
||||
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY) + Ystride;
|
||||
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * MValueX);
|
||||
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * MValueY);
|
||||
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);
|
||||
if (Width < 0)
|
||||
{
|
||||
X += Width;
|
||||
|
@ -988,7 +995,7 @@ void UpdateViewport()
|
|||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
// Update the view port for clearing the picture
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = targetRc.left;
|
||||
vp.Y = targetRc.top;
|
||||
|
@ -1062,7 +1069,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
return;
|
||||
}
|
||||
|
||||
Renderer::ResetAPIState();
|
||||
ResetAPIState();
|
||||
if(g_ActiveConfig.bAnaglyphStereo)
|
||||
{
|
||||
if(RightFrame)
|
||||
|
@ -1090,6 +1097,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
D3DVIEWPORT9 vp;
|
||||
|
||||
// Clear full target screen (edges, borders etc)
|
||||
vp.X = 0;
|
||||
vp.Y = 0;
|
||||
vp.Width = s_backbuffer_width;
|
||||
|
@ -1105,6 +1114,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
|
||||
if (X < 0) X = 0;
|
||||
if (Y < 0) Y = 0;
|
||||
if (X > s_backbuffer_width) X = s_backbuffer_width;
|
||||
|
@ -1113,6 +1123,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
if (Height < 0) Height = 0;
|
||||
if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X;
|
||||
if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y;
|
||||
|
||||
vp.X = X;
|
||||
vp.Y = Y;
|
||||
vp.Width = Width;
|
||||
|
@ -1125,14 +1136,16 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
const XFBSource* xfbSource = NULL;
|
||||
|
||||
if(g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
const XFBSource* xfbSource;
|
||||
|
||||
// draw each xfb source
|
||||
// Render to the real buffer now.
|
||||
for (u32 i = 0; i < xfbCount; ++i)
|
||||
{
|
||||
xfbSource = xfbSourceList[i];
|
||||
|
||||
MathUtil::Rectangle<float> sourceRc;
|
||||
|
||||
sourceRc.left = 0;
|
||||
|
@ -1142,7 +1155,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
|
||||
MathUtil::Rectangle<float> drawRc;
|
||||
|
||||
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||
if (!g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
// use virtual xfb with offset
|
||||
int xfbHeight = xfbSource->srcHeight;
|
||||
|
@ -1154,17 +1167,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||
|
||||
if (!g_ActiveConfig.bAutoScale)
|
||||
{
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
float vScale = (float)fbHeight / (float)s_backbuffer_height;
|
||||
float hScale = (float)fbWidth / (float)s_backbuffer_width;
|
||||
|
||||
drawRc.top *= vScale;
|
||||
drawRc.bottom *= vScale;
|
||||
drawRc.left *= hScale;
|
||||
drawRc.right *= hScale;
|
||||
}
|
||||
// The following code disables auto stretch. Kept for reference.
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
|
||||
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
|
||||
//drawRc.top *= vScale;
|
||||
//drawRc.bottom *= vScale;
|
||||
//drawRc.left *= hScale;
|
||||
//drawRc.right *= hScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1179,17 +1189,19 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
}
|
||||
else
|
||||
{
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(rc);
|
||||
D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode));
|
||||
}
|
||||
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
|
||||
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
|
||||
|
||||
if(g_ActiveConfig.bAnaglyphStereo)
|
||||
{
|
||||
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
|
||||
}
|
||||
|
||||
vp.X = 0;
|
||||
vp.Y = 0;
|
||||
vp.Width = s_backbuffer_width;
|
||||
|
@ -1197,6 +1209,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
D3D::dev->SetViewport(&vp);
|
||||
|
||||
// Save screenshot
|
||||
if (s_bScreenshot)
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
|
@ -1302,17 +1316,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
}
|
||||
|
||||
u32 newAA = g_ActiveConfig.iMultisampleMode;
|
||||
u32 newEFBScale = g_ActiveConfig.iEFBScale;
|
||||
if (newAA != s_LastAA || newEFBScale != s_LastEFBScale || xfbchanged || WindowResized)
|
||||
|
||||
if (xfbchanged || WindowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale)
|
||||
{
|
||||
s_LastAA = newAA;
|
||||
s_LastEFBScale = newEFBScale;
|
||||
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
xScale = yScale = 1.0f;
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1321,6 +1335,7 @@ 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:
|
||||
|
@ -1339,8 +1354,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
|
||||
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->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||
if (WindowResized)
|
||||
|
@ -1379,7 +1399,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
// Flip/present backbuffer to frontbuffer here
|
||||
D3D::Present();
|
||||
D3D::BeginFrame();
|
||||
Renderer::RestoreAPIState();
|
||||
RestoreAPIState();
|
||||
|
||||
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
|
||||
UpdateViewport();
|
||||
|
|
|
@ -305,36 +305,6 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
|||
if (pcfmt == PC_TEX_FMT_NONE)
|
||||
pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
|
||||
|
||||
D3DFORMAT d3d_fmt;
|
||||
bool swap_r_b = false;
|
||||
switch (pcfmt) {
|
||||
case PC_TEX_FMT_BGRA32:
|
||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||
break;
|
||||
case PC_TEX_FMT_RGBA32:
|
||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||
swap_r_b = true;
|
||||
break;
|
||||
case PC_TEX_FMT_RGB565:
|
||||
d3d_fmt = D3DFMT_R5G6B5;
|
||||
break;
|
||||
case PC_TEX_FMT_IA4_AS_IA8:
|
||||
d3d_fmt = D3DFMT_A8L8;
|
||||
break;
|
||||
case PC_TEX_FMT_I8:
|
||||
case PC_TEX_FMT_I4_AS_I8:
|
||||
d3d_fmt = D3DFMT_A8P8; // A hack which means the format is a packed
|
||||
// 8-bit intensity texture. It is unpacked
|
||||
// to A8L8 in D3DTexture.cpp
|
||||
break;
|
||||
case PC_TEX_FMT_IA8:
|
||||
d3d_fmt = D3DFMT_A8L8;
|
||||
break;
|
||||
case PC_TEX_FMT_DXT1:
|
||||
d3d_fmt = D3DFMT_DXT1;
|
||||
break;
|
||||
}
|
||||
|
||||
entry.oldpixel = ((u32 *)ptr)[0];
|
||||
if (g_ActiveConfig.bSafeTextureCache || entry.isDynamic)
|
||||
entry.hash = hash_value;
|
||||
|
@ -354,6 +324,40 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
|||
if(TexLevels > (maxlevel + 1) && maxlevel > 0)
|
||||
TexLevels = (maxlevel + 1);
|
||||
entry.MipLevels = maxlevel;
|
||||
|
||||
D3DFORMAT d3d_fmt;
|
||||
bool swap_r_b = false;
|
||||
|
||||
switch (pcfmt)
|
||||
{
|
||||
case PC_TEX_FMT_BGRA32:
|
||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||
break;
|
||||
case PC_TEX_FMT_RGBA32:
|
||||
d3d_fmt = D3DFMT_A8R8G8B8;
|
||||
swap_r_b = true;
|
||||
break;
|
||||
case PC_TEX_FMT_RGB565:
|
||||
d3d_fmt = D3DFMT_R5G6B5;
|
||||
break;
|
||||
case PC_TEX_FMT_IA4_AS_IA8:
|
||||
d3d_fmt = D3DFMT_A8L8;
|
||||
break;
|
||||
case PC_TEX_FMT_I8:
|
||||
case PC_TEX_FMT_I4_AS_I8:
|
||||
// A hack which means the format is a packed
|
||||
// 8-bit intensity texture. It is unpacked
|
||||
// to A8L8 in D3DTexture.cpp
|
||||
d3d_fmt = D3DFMT_A8P8;
|
||||
break;
|
||||
case PC_TEX_FMT_IA8:
|
||||
d3d_fmt = D3DFMT_A8L8;
|
||||
break;
|
||||
case PC_TEX_FMT_DXT1:
|
||||
d3d_fmt = D3DFMT_DXT1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skip_texture_create)
|
||||
{
|
||||
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b, TexLevels);
|
||||
|
|
|
@ -437,11 +437,9 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
|
|||
cacheBytes = 64;
|
||||
|
||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||
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);
|
||||
TextureCache::MakeRangeDynamic(address,size_in_bytes);
|
||||
u64 Hashvalue = 0;
|
||||
Hashvalue = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
return Hashvalue;
|
||||
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
}
|
||||
|
||||
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
|
||||
|
|
|
@ -197,7 +197,7 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) cons
|
|||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||
// required.
|
||||
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(sourceRc);
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||
|
||||
// Resolve.
|
||||
|
@ -227,7 +227,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) cons
|
|||
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
|
||||
// required.
|
||||
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(sourceRc);
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
|
||||
|
||||
// Resolve.
|
||||
|
@ -262,18 +262,6 @@ const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32
|
|||
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||
}
|
||||
|
||||
TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc) const
|
||||
{
|
||||
TargetRectangle result;
|
||||
float XScale = Renderer::GetTargetScaleX();
|
||||
float YScale = Renderer::GetTargetScaleY();
|
||||
result.left = rc.left * XScale;
|
||||
result.top = ((EFB_HEIGHT - rc.top) * YScale);
|
||||
result.right = rc.right * XScale ;
|
||||
result.bottom = ((EFB_HEIGHT - rc.bottom) * YScale);
|
||||
return result;
|
||||
}
|
||||
|
||||
FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
|
||||
{
|
||||
u32 srcLower = xfbAddr;
|
||||
|
@ -373,7 +361,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
|||
|
||||
it->xfbSource.texWidth = Renderer::GetTargetWidth();
|
||||
it->xfbSource.texHeight = Renderer::GetTargetHeight();
|
||||
it->xfbSource.sourceRc = ConvertEFBRectangle(sourceRc);
|
||||
it->xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
|
||||
xfbTexture = it->xfbSource.texture;
|
||||
|
||||
|
@ -417,7 +405,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
|
|||
newVirt.xfbSource.texture = xfbTexture;
|
||||
newVirt.xfbSource.texWidth = m_targetWidth;
|
||||
newVirt.xfbSource.texHeight = m_targetHeight;
|
||||
newVirt.xfbSource.sourceRc = ConvertEFBRectangle(sourceRc);
|
||||
newVirt.xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
|
||||
|
||||
// Add the new Virtual XFB to the list
|
||||
|
||||
|
|
|
@ -106,8 +106,6 @@ public:
|
|||
// Resolved framebuffer is only used in MSAA mode.
|
||||
GLuint GetResolvedFramebuffer() const { return m_resolvedFramebuffer; }
|
||||
|
||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) const;
|
||||
|
||||
void SetFramebuffer(GLuint fb);
|
||||
|
||||
// If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.
|
||||
|
|
|
@ -164,16 +164,8 @@ THREAD_RETURN XEventThread(void *pArg)
|
|||
case XK_3:
|
||||
OSDChoice = 1;
|
||||
// Toggle native resolution
|
||||
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
|
||||
g_Config.bNativeResolution = true;
|
||||
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
|
||||
{
|
||||
g_Config.bNativeResolution = false;
|
||||
if (Renderer::Allow2x())
|
||||
g_Config.b2xResolution = true;
|
||||
}
|
||||
else if (Renderer::AllowCustom())
|
||||
g_Config.b2xResolution = false;
|
||||
g_Config.iEFBScale = g_Config.iEFBScale + 1;
|
||||
if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
|
||||
break;
|
||||
case XK_4:
|
||||
OSDChoice = 2;
|
||||
|
|
|
@ -39,14 +39,12 @@ BEGIN_EVENT_TABLE(GFXConfigDialogOGL,wxDialog)
|
|||
EVT_CHECKBOX(ID_VSYNC, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHOICE(ID_MAXANISOTROPY, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHOICE(ID_MSAAMODECB, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_NATIVERESOLUTION, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_2X_RESOLUTION, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHOICE(ID_EFBSCALEMODE, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_USEXFB, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_USEREALXFB, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_FORCEFILTERING, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_USENATIVEMIPS, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_EFBSCALEDCOPY, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_AUTOSCALE, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_WIDESCREENHACK, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHOICE(ID_ASPECT, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
EVT_CHECKBOX(ID_CROP, GFXConfigDialogOGL::GeneralSettingsChanged)
|
||||
|
@ -154,6 +152,13 @@ void GFXConfigDialogOGL::LoadShaders()
|
|||
|
||||
void GFXConfigDialogOGL::InitializeGUILists()
|
||||
{
|
||||
// EFB Scale
|
||||
arrayStringFor_EFBScale.Add(wxT("Auto (fractional)"));
|
||||
arrayStringFor_EFBScale.Add(wxT("Auto (integral)"));
|
||||
arrayStringFor_EFBScale.Add(wxT("Native"));
|
||||
arrayStringFor_EFBScale.Add(wxT("2x"));
|
||||
arrayStringFor_EFBScale.Add(wxT("3x"));
|
||||
|
||||
// Keep Aspect Ratio
|
||||
arrayStringFor_AspectRatio.Add(wxT("Auto Aspect (recommended)"));
|
||||
arrayStringFor_AspectRatio.Add(wxT("Force 16:9 Widescreen"));
|
||||
|
@ -191,8 +196,7 @@ void GFXConfigDialogOGL::InitializeGUILists()
|
|||
void GFXConfigDialogOGL::InitializeGUIValues()
|
||||
{
|
||||
// General Display Settings
|
||||
m_NativeResolution->SetValue(g_Config.bNativeResolution);
|
||||
m_2xResolution->SetValue(g_Config.b2xResolution);
|
||||
m_EFBScaleMode->SetSelection(g_Config.iEFBScale);
|
||||
|
||||
m_KeepAR->SetSelection(g_Config.iAspectRatio);
|
||||
m_Crop->SetValue(g_Config.bCrop);
|
||||
|
@ -202,7 +206,6 @@ void GFXConfigDialogOGL::InitializeGUIValues()
|
|||
m_VSync->SetValue(g_Config.bVSync);
|
||||
m_UseXFB->SetValue(g_Config.bUseXFB);
|
||||
m_UseRealXFB->SetValue(g_Config.bUseRealXFB);
|
||||
m_AutoScale->SetValue(g_Config.bAutoScale);
|
||||
m_WidescreenHack->SetValue(g_Config.bWidescreenHack);
|
||||
m_UseNativeMips->SetValue(g_Config.bUseNativeMips);
|
||||
m_EFBScaledCopy->SetValue(g_Config.bCopyEFBScaled);
|
||||
|
@ -260,14 +263,12 @@ void GFXConfigDialogOGL::InitializeGUIValues()
|
|||
void GFXConfigDialogOGL::InitializeGUITooltips()
|
||||
{
|
||||
// Tool tips
|
||||
m_NativeResolution->SetToolTip(
|
||||
wxT("This will use the game's native resolution and stretch it to fill the")
|
||||
wxT("\nwindow instead of changing the internal display resolution. It")
|
||||
m_EFBScaleMode->SetToolTip(
|
||||
wxT("This will change the game's native resolution and stretch it to fill the")
|
||||
wxT("\nwindow instead of changing the display resolution. It")
|
||||
wxT("\nmay result in a blurrier image, but it may also give a higher")
|
||||
wxT("\nFPS if you have a slow graphics card.")
|
||||
wxT("\n\nApplies instanty during gameplay: <Yes>"));
|
||||
m_2xResolution->SetToolTip(wxT(
|
||||
"Applies instanty during gameplay: <Yes, if allowed>"));
|
||||
wxT("\n\nApplies instantly during gameplay: <Yes>"));
|
||||
m_KeepAR->SetToolTip(
|
||||
wxT("This sets the aspect ratio of the image.")
|
||||
wxT("\nThe Widescreen hack may cause graphical issues in some games !")
|
||||
|
@ -358,9 +359,8 @@ void GFXConfigDialogOGL::CreateGUIControls()
|
|||
|
||||
// General Display Settings
|
||||
sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Basic Display Settings"));
|
||||
wxStaticText *IRText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Resolution:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Native"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_2xResolution = new wxCheckBox(m_PageGeneral, ID_2X_RESOLUTION, wxT("2x"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
wxStaticText *IRText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Internal Resolution:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_EFBScaleMode = new wxChoice(m_PageGeneral, ID_EFBSCALEMODE, wxDefaultPosition, wxDefaultSize, arrayStringFor_EFBScale);
|
||||
// Aspect ratio / positioning controls
|
||||
wxStaticText *KeepARText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Keep aspect ratio:"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_KeepAR = new wxChoice(m_PageGeneral, ID_ASPECT, wxDefaultPosition, wxDefaultSize, arrayStringFor_AspectRatio);
|
||||
|
@ -375,7 +375,6 @@ void GFXConfigDialogOGL::CreateGUIControls()
|
|||
m_VSync = new wxCheckBox(m_PageGeneral, ID_VSYNC, wxT("VSync (req. restart)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_UseXFB = new wxCheckBox(m_PageGeneral, ID_USEXFB, wxT("Use XFB"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_UseRealXFB = new wxCheckBox(m_PageGeneral, ID_USEREALXFB, wxT("Use Real XFB"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_AutoScale = new wxCheckBox(m_PageGeneral, ID_AUTOSCALE, wxT("Auto scale (try to remove borders)"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_WidescreenHack = new wxCheckBox(m_PageGeneral, ID_WIDESCREENHACK, wxT("Wide screen hack"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_UseNativeMips = new wxCheckBox(m_PageGeneral, ID_USENATIVEMIPS, wxT("Use Native Mips"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_EFBScaledCopy = new wxCheckBox(m_PageGeneral, ID_EFBSCALEDCOPY, wxT("EFB Scaled Copy"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
|
@ -397,8 +396,7 @@ void GFXConfigDialogOGL::CreateGUIControls()
|
|||
sBasic = new wxGridBagSizer(0, 0);
|
||||
|
||||
sBasic->Add(IRText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sBasic->Add(m_NativeResolution, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sBasic->Add(m_2xResolution, wxGBPosition(0, 2), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sBasic->Add(m_EFBScaleMode, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL, 5);
|
||||
|
||||
sBasic->Add(KeepARText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
|
||||
sBasic->Add(m_KeepAR, wxGBPosition(1, 1), wxGBSpan(1, 1), wxALL, 5);
|
||||
|
@ -413,7 +411,6 @@ void GFXConfigDialogOGL::CreateGUIControls()
|
|||
sBasicAdvanced->Add(m_VSync, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_UseXFB, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_UseRealXFB, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_AutoScale, wxGBPosition(4, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_WidescreenHack, wxGBPosition(5, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_UseNativeMips, wxGBPosition(6, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
sBasicAdvanced->Add(m_EFBScaledCopy, wxGBPosition(7, 0), wxGBSpan(1, 2), wxALL, 5);
|
||||
|
@ -589,15 +586,9 @@ void GFXConfigDialogOGL::GeneralSettingsChanged(wxCommandEvent& event)
|
|||
{
|
||||
switch (event.GetId())
|
||||
{
|
||||
case ID_NATIVERESOLUTION:
|
||||
g_Config.bNativeResolution = m_NativeResolution->IsChecked();
|
||||
// Don't allow 1x and 2x at the same time
|
||||
if (g_Config.bNativeResolution) { g_Config.b2xResolution = false; m_2xResolution->SetValue(false); }
|
||||
break;
|
||||
case ID_2X_RESOLUTION:
|
||||
g_Config.b2xResolution = m_2xResolution->IsChecked();
|
||||
// Don't allow 1x and 2x at the same time
|
||||
if (g_Config.b2xResolution) { g_Config.bNativeResolution = false; m_NativeResolution->SetValue(false); }
|
||||
case ID_EFBSCALEMODE:
|
||||
g_Config.iEFBScale = m_EFBScaleMode->GetSelection();
|
||||
|
||||
break;
|
||||
case ID_VSYNC:
|
||||
g_Config.bVSync = m_VSync->IsChecked();
|
||||
|
@ -614,9 +605,6 @@ void GFXConfigDialogOGL::GeneralSettingsChanged(wxCommandEvent& event)
|
|||
case ID_EFBSCALEDCOPY:
|
||||
g_Config.bCopyEFBScaled = m_EFBScaledCopy->IsChecked();
|
||||
break;
|
||||
case ID_AUTOSCALE:
|
||||
g_Config.bAutoScale = m_AutoScale->IsChecked();
|
||||
break;
|
||||
case ID_ASPECT:
|
||||
g_Config.iAspectRatio = m_KeepAR->GetSelection();
|
||||
break;
|
||||
|
@ -775,20 +763,14 @@ void GFXConfigDialogOGL::UpdateGUI()
|
|||
m_UseXFB->SetValue(true);
|
||||
|
||||
// XFB looks much better if the copy comes from native resolution.
|
||||
g_Config.bNativeResolution = true;
|
||||
m_NativeResolution->SetValue(true);
|
||||
//also disable 2x, since it might leave both checked.
|
||||
g_Config.b2xResolution = false;
|
||||
m_2xResolution->SetValue(false);
|
||||
g_Config.iEFBScale = 2;
|
||||
m_EFBScaleMode->SetSelection(g_Config.iEFBScale);
|
||||
}
|
||||
m_AutoScale->Enable(!g_Config.bUseRealXFB);
|
||||
m_UseXFB->Enable(!g_Config.bUseRealXFB);
|
||||
|
||||
// Resolution settings
|
||||
//disable native/2x choice when real xfb is on. native simply looks best, as ector noted above.
|
||||
//besides, it would look odd if one disabled native, and it came back on again.
|
||||
m_NativeResolution->Enable(!g_Config.bUseRealXFB);
|
||||
m_2xResolution->Enable(!g_Config.bUseRealXFB && (!g_Config.bRunning || Renderer::Allow2x()));
|
||||
m_EFBScaleMode->Enable(!g_Config.bUseRealXFB);
|
||||
|
||||
|
||||
// Disable the Copy to options when EFBCopy is disabled
|
||||
m_Radio_CopyEFBToRAM->Enable(!(g_Config.bEFBCopyDisable));
|
||||
|
|
|
@ -90,7 +90,7 @@ class GFXConfigDialogOGL : public wxDialog
|
|||
wxPanel *m_PageGeneral;
|
||||
wxPanel *m_PageAdvanced;
|
||||
wxCheckBox *m_VSync;
|
||||
wxCheckBox *m_NativeResolution, *m_2xResolution;
|
||||
wxChoice *m_EFBScaleMode;
|
||||
wxCheckBox *m_WidescreenHack;
|
||||
wxCheckBox *m_ForceFiltering;
|
||||
wxCheckBox *m_Crop;
|
||||
|
@ -98,7 +98,6 @@ class GFXConfigDialogOGL : public wxDialog
|
|||
wxCheckBox *m_UseNativeMips;
|
||||
wxCheckBox *m_EFBScaledCopy;
|
||||
wxCheckBox *m_UseRealXFB;
|
||||
wxCheckBox *m_AutoScale;
|
||||
wxChoice *m_MaxAnisotropyCB;
|
||||
wxChoice *m_MSAAModeCB, *m_PhackvalueCB, *m_PostShaderCB, *m_KeepAR;
|
||||
|
||||
|
@ -136,6 +135,7 @@ class GFXConfigDialogOGL : public wxDialog
|
|||
wxCheckBox *m_ScreenSize;
|
||||
|
||||
wxArrayString arrayStringFor_FullscreenCB;
|
||||
wxArrayString arrayStringFor_EFBScale;
|
||||
wxArrayString arrayStringFor_AspectRatio;
|
||||
wxArrayString arrayStringFor_MaxAnisotropyCB;
|
||||
wxArrayString arrayStringFor_MSAAModeCB;
|
||||
|
@ -149,14 +149,13 @@ class GFXConfigDialogOGL : public wxDialog
|
|||
ID_PAGEADVANCED,
|
||||
|
||||
ID_VSYNC,
|
||||
ID_NATIVERESOLUTION, ID_2X_RESOLUTION,
|
||||
ID_EFBSCALEMODE,
|
||||
ID_ASPECT,
|
||||
ID_CROP,
|
||||
ID_USEREALXFB,
|
||||
ID_USEXFB,
|
||||
ID_USENATIVEMIPS,
|
||||
ID_EFBSCALEDCOPY,
|
||||
ID_AUTOSCALE,
|
||||
ID_WIDESCREENHACK,
|
||||
|
||||
ID_FORCEFILTERING,
|
||||
|
|
|
@ -89,12 +89,8 @@ void OSDMenu(WPARAM wParam)
|
|||
case '3':
|
||||
OSDChoice = 1;
|
||||
// Toggle native resolution
|
||||
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
|
||||
g_Config.bNativeResolution = true;
|
||||
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
|
||||
{ g_Config.bNativeResolution = false; if (Renderer::Allow2x()) {g_Config.b2xResolution = true;} }
|
||||
else if (Renderer::AllowCustom())
|
||||
g_Config.b2xResolution = false;
|
||||
g_Config.iEFBScale = g_Config.iEFBScale + 1;
|
||||
if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
|
||||
break;
|
||||
case '4':
|
||||
OSDChoice = 2;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
static int s_nMaxPixelInstructions;
|
||||
static GLuint s_ColorMatrixProgram = 0;
|
||||
static GLuint s_DepthMatrixProgram = 0;
|
||||
PixelShaderCache::PSCache PixelShaderCache::pshaders;
|
||||
PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||
PIXELSHADERUID PixelShaderCache::s_curuid;
|
||||
bool PixelShaderCache::s_displayCompileAlert;
|
||||
GLuint PixelShaderCache::CurrentShader;
|
||||
|
@ -177,27 +177,30 @@ void PixelShaderCache::Shutdown()
|
|||
s_ColorMatrixProgram = 0;
|
||||
glDeleteProgramsARB(1, &s_DepthMatrixProgram);
|
||||
s_DepthMatrixProgram = 0;
|
||||
PSCache::iterator iter = pshaders.begin();
|
||||
for (; iter != pshaders.end(); iter++)
|
||||
PSCache::iterator iter = PixelShaders.begin();
|
||||
for (; iter != PixelShaders.end(); iter++)
|
||||
iter->second.Destroy();
|
||||
pshaders.clear();
|
||||
PixelShaders.clear();
|
||||
}
|
||||
|
||||
FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
|
||||
FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlpha,u32 components)
|
||||
{
|
||||
DVSTARTPROFILE();
|
||||
PIXELSHADERUID uid;
|
||||
GetPixelShaderId(&uid, dstAlphaEnable ? 1 : 0);
|
||||
if (uid == last_pixel_shader_uid && pshaders[uid].frameCount == frameCount)
|
||||
GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
|
||||
|
||||
// Check if the shader is already set
|
||||
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||
{
|
||||
return pShaderLast;
|
||||
}
|
||||
|
||||
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
|
||||
|
||||
PSCache::iterator iter = pshaders.find(uid);
|
||||
PSCache::iterator iter = PixelShaders.find(uid);
|
||||
|
||||
if (iter != pshaders.end()) {
|
||||
if (iter != PixelShaders.end())
|
||||
{
|
||||
iter->second.frameCount = frameCount;
|
||||
PSCacheEntry &entry = iter->second;
|
||||
if (&entry.shader != pShaderLast)
|
||||
|
@ -209,10 +212,10 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
|
|||
}
|
||||
|
||||
//Make an entry in the table
|
||||
PSCacheEntry& newentry = pshaders[uid];
|
||||
PSCacheEntry& newentry = PixelShaders[uid];
|
||||
newentry.frameCount = frameCount;
|
||||
pShaderLast = &newentry.shader;
|
||||
const char *code = GeneratePixelShaderCode(dstAlphaEnable,API_OPENGL,components);
|
||||
const char *code = GeneratePixelShaderCode(dstAlpha,API_OPENGL,components);
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||
|
@ -235,7 +238,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
|
|||
}
|
||||
|
||||
INCSTAT(stats.numPixelShadersCreated);
|
||||
SETSTAT(stats.numPixelShadersAlive, pshaders.size());
|
||||
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
|
||||
return pShaderLast;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class PixelShaderCache
|
|||
|
||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||
|
||||
static PSCache pshaders;
|
||||
static PSCache PixelShaders;
|
||||
|
||||
static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ static int s_MSAACoverageSamples = 0;
|
|||
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
|
||||
static bool s_bHaveCoverageMSAA = false;
|
||||
static u32 s_blendMode;
|
||||
static u32 s_LastEFBScale;
|
||||
|
||||
static volatile bool s_bScreenshot = false;
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
|
@ -105,6 +106,9 @@ 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;
|
||||
|
@ -348,29 +352,40 @@ bool Renderer::Init()
|
|||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
|
||||
if(!g_ActiveConfig.bNativeResolution)
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_ActiveConfig.b2xResolution)
|
||||
{
|
||||
xScale = 2.0f;
|
||||
yScale = 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
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;
|
||||
};
|
||||
|
||||
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
|
||||
// options while running
|
||||
g_Config.bRunning = true;
|
||||
|
@ -488,7 +503,7 @@ bool Renderer::Init()
|
|||
return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown(void)
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
g_Config.bRunning = false;
|
||||
UpdateActiveConfig();
|
||||
|
@ -530,15 +545,14 @@ int Renderer::GetTargetHeight()
|
|||
return s_target_height;
|
||||
}
|
||||
|
||||
// Return the custom resolution
|
||||
int Renderer::GetCustomWidth()
|
||||
int Renderer::GetFullTargetWidth()
|
||||
{
|
||||
return s_backbuffer_width;
|
||||
return s_Fulltarget_width;
|
||||
}
|
||||
|
||||
int Renderer::GetCustomHeight()
|
||||
int Renderer::GetFullTargetHeight()
|
||||
{
|
||||
return s_backbuffer_height;
|
||||
return s_Fulltarget_height;
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleX()
|
||||
|
@ -561,17 +575,6 @@ float Renderer::GetXFBScaleY()
|
|||
return yScale;
|
||||
}
|
||||
|
||||
// Return the framebuffer size
|
||||
int Renderer::GetFrameBufferWidth()
|
||||
{
|
||||
return s_target_width;
|
||||
}
|
||||
|
||||
int Renderer::GetFrameBufferHeight()
|
||||
{
|
||||
return s_target_height;
|
||||
}
|
||||
|
||||
// Create On-Screen-Messages
|
||||
void Renderer::DrawDebugText()
|
||||
{
|
||||
|
@ -657,16 +660,26 @@ void Renderer::DrawDebugText()
|
|||
std::string T1 = "", T2 = "";
|
||||
std::vector<std::string> T0;
|
||||
|
||||
int W, H;
|
||||
W = OpenGL_GetBackbufferWidth();
|
||||
H = OpenGL_GetBackbufferHeight();
|
||||
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 OSDM1 =
|
||||
g_ActiveConfig.bNativeResolution || g_ActiveConfig.b2xResolution ?
|
||||
(g_ActiveConfig.bNativeResolution ?
|
||||
StringFromFormat("%i x %i (native)", OSDInternalW, OSDInternalH)
|
||||
: StringFromFormat("%i x %i (2x)", OSDInternalW, OSDInternalH))
|
||||
: StringFromFormat("%i x %i (custom)", W, H);
|
||||
std::string OSDM21;
|
||||
switch(g_ActiveConfig.iAspectRatio)
|
||||
{
|
||||
|
@ -740,7 +753,14 @@ void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
|||
|
||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
{
|
||||
return g_framebufferManager.ConvertEFBRectangle(rc);
|
||||
TargetRectangle result;
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
result.left = (int)(rc.left * EFBxScale) + Xstride;
|
||||
result.top = (int)((EFB_HEIGHT - rc.top) * EFByScale) + Ystride;
|
||||
result.right = (int)(rc.right * EFBxScale) - (Xstride * 2);
|
||||
result.bottom = (int)((EFB_HEIGHT - rc.bottom) * EFByScale) - (Ystride * 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
|
@ -778,39 +798,51 @@ bool Renderer::SetScissorRect()
|
|||
{
|
||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||
int yoff = bpmem.scissorOffset.y * 2 - 342;
|
||||
|
||||
float rc_left = (float)bpmem.scissorTL.x - xoff - 342; // left = 0
|
||||
if (rc_left < 0) rc_left = 0;
|
||||
|
||||
float rc_top = (float)bpmem.scissorTL.y - yoff - 342; // right = 0
|
||||
if (rc_top < 0) rc_top = 0;
|
||||
|
||||
float rc_right = (float)bpmem.scissorBR.x - xoff - 341; // right = 640
|
||||
if (rc_right > EFB_WIDTH) rc_right = EFB_WIDTH;
|
||||
|
||||
float rc_bottom = (float)bpmem.scissorBR.y - yoff - 341; // bottom = 480
|
||||
|
||||
// TODO: Sanity checks require further testing
|
||||
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;
|
||||
|
||||
if(rc_left > rc_right)
|
||||
if (rc_left > rc_right)
|
||||
{
|
||||
int temp = rc_right;
|
||||
rc_right = rc_left;
|
||||
rc_left = temp;
|
||||
}
|
||||
if(rc_top > rc_bottom)
|
||||
if (rc_top > rc_bottom)
|
||||
{
|
||||
int temp = rc_bottom;
|
||||
rc_bottom = rc_top;
|
||||
rc_top = temp;
|
||||
}
|
||||
|
||||
int Xstride = (s_Fulltarget_width - s_target_width) / 2;
|
||||
int Ystride = (s_Fulltarget_height - s_target_height) / 2;
|
||||
|
||||
rc_left = (int)(rc_left * EFBxScale);// + Xstride;
|
||||
rc_top = (int)((rc_bottom - rc_top) * EFByScale);// + Ystride;
|
||||
rc_right = (int)((rc_right - rc_left) * EFBxScale);
|
||||
rc_bottom = (int)((EFB_HEIGHT - rc_bottom) * EFByScale); // -Ystride?
|
||||
|
||||
// Check that the coordinates are good
|
||||
if (rc_right != rc_left && rc_bottom != rc_top)
|
||||
{
|
||||
glScissor(
|
||||
(int)(rc_left * EFBxScale), // x = 0 for example
|
||||
(int)((EFB_HEIGHT - rc_bottom) * EFByScale), // y = 0 for example
|
||||
(int)((rc_right - rc_left)* EFBxScale), // width = 640 for example
|
||||
(int)((rc_bottom - rc_top) * EFByScale) // height = 480 for example
|
||||
(int)(rc_left), // x = 0 for example
|
||||
(int)(rc_bottom), // y = 0 for example
|
||||
(int)(rc_right), // width = 640 for example
|
||||
(int)(rc_top) // height = 480 for example
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -835,7 +867,7 @@ void Renderer::SetColorMask()
|
|||
|
||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||
{
|
||||
if(!g_ActiveConfig.bEFBAccessEnable)
|
||||
if (!g_ActiveConfig.bEFBAccessEnable)
|
||||
return 0;
|
||||
|
||||
// Get the rectangular target region covered by the EFB pixel
|
||||
|
@ -845,7 +877,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
efbPixelRc.right = x + 1;
|
||||
efbPixelRc.bottom = y + 1;
|
||||
|
||||
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
||||
TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
|
||||
|
||||
// TODO (FIX) : currently, AA path is broken/offset and doesn't return the correct pixel
|
||||
switch (type)
|
||||
|
@ -929,42 +961,44 @@ void UpdateViewport()
|
|||
// [3] = xorig + width/2 + 342
|
||||
// [4] = yorig + height/2 + 342
|
||||
// [5] = 16777215 * farz
|
||||
float scissorXOff = float(bpmem.scissorOffset.x) * 2.0f; // 342
|
||||
float scissorYOff = float(bpmem.scissorOffset.y) * 2.0f; // 342
|
||||
|
||||
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;
|
||||
|
||||
// Stretch picture with increased internal resolution
|
||||
int GLx = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff) *
|
||||
EFBxScale);
|
||||
int GLy = (int)ceil(
|
||||
(float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + scissorYOff) *
|
||||
EFByScale);
|
||||
int GLWidth = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
||||
int GLHeight = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
||||
int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * EFBxScale);
|
||||
int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * EFByScale);
|
||||
int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
|
||||
int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
|
||||
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
||||
double GLFar = xfregs.rawViewport[5] / 16777216.0f;
|
||||
if(GLWidth < 0)
|
||||
if (Width < 0)
|
||||
{
|
||||
GLx += GLWidth;
|
||||
GLWidth*=-1;
|
||||
X += Width;
|
||||
Width*=-1;
|
||||
}
|
||||
if(GLHeight < 0)
|
||||
if (Height < 0)
|
||||
{
|
||||
GLy += GLHeight;
|
||||
GLHeight *= -1;
|
||||
Y += Height;
|
||||
Height *= -1;
|
||||
}
|
||||
// Update the view port
|
||||
glViewport(GLx, GLy, GLWidth, GLHeight);
|
||||
glViewport(X, Y, Width, Height);
|
||||
glDepthRange(GLNear, GLFar);
|
||||
}
|
||||
|
||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
// Update the view port for clearing the picture
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
glViewport(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
glScissor(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
|
||||
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
glScissor(targetRc.left, targetRc.bottom, targetRc.GetWidth(), targetRc.GetHeight());
|
||||
|
||||
VertexShaderManager::SetViewportChanged();
|
||||
|
||||
|
@ -1048,10 +1082,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
}
|
||||
|
||||
DVSTARTPROFILE();
|
||||
|
||||
ResetAPIState();
|
||||
TargetRectangle back_rc;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &back_rc);
|
||||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect);
|
||||
|
||||
// Make sure that the wireframe setting doesn't screw up the screen copy.
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
@ -1063,7 +1096,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
TextureCache::DisableStage(i);
|
||||
|
||||
// Update GLViewPort
|
||||
glViewport(back_rc.left, back_rc.bottom, back_rc.GetWidth(), back_rc.GetHeight());
|
||||
glViewport(dst_rect.left, dst_rect.bottom, dst_rect.GetWidth(), dst_rect.GetHeight());
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
|
@ -1094,21 +1127,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
|
||||
TargetRectangle sourceRc;
|
||||
|
||||
if (g_ActiveConfig.bAutoScale || g_ActiveConfig.bUseXFB)
|
||||
{
|
||||
sourceRc = xfbSource->sourceRc;
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceRc.left = 0;
|
||||
sourceRc.top = xfbSource->texHeight;
|
||||
sourceRc.right = xfbSource->texWidth;
|
||||
sourceRc.bottom = 0;
|
||||
}
|
||||
sourceRc = xfbSource->sourceRc;
|
||||
|
||||
MathUtil::Rectangle<float> drawRc;
|
||||
|
||||
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||
if (!g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
// use virtual xfb with offset
|
||||
int xfbHeight = xfbSource->srcHeight;
|
||||
|
@ -1120,17 +1143,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
drawRc.left = -(xfbWidth / (float)fbWidth);
|
||||
drawRc.right = (xfbWidth / (float)fbWidth);
|
||||
|
||||
if (!g_ActiveConfig.bAutoScale)
|
||||
{
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
float vScale = (float)fbHeight / (float)back_rc.GetHeight();
|
||||
float hScale = (float)fbWidth / (float)back_rc.GetWidth();
|
||||
|
||||
drawRc.top *= vScale;
|
||||
drawRc.bottom *= vScale;
|
||||
drawRc.left *= hScale;
|
||||
drawRc.right *= hScale;
|
||||
}
|
||||
// The following code disables auto stretch. Kept for reference.
|
||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||
//float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
|
||||
//float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
|
||||
//drawRc.top *= vScale;
|
||||
//drawRc.bottom *= vScale;
|
||||
//drawRc.left *= hScale;
|
||||
//drawRc.right *= hScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1192,7 +1212,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
}
|
||||
else
|
||||
{
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(rc);
|
||||
// Render to the real buffer now.
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer
|
||||
|
@ -1234,12 +1254,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
glVertex2f( 1, -1);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
|
||||
TextureCache::DisableStage(0);
|
||||
if(g_ActiveConfig.bAnaglyphStereo)
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// Wireframe
|
||||
if (g_ActiveConfig.bWireFrame)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
@ -1249,7 +1268,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
// Save screenshot
|
||||
SaveRenderTarget(s_sScreenshotName.c_str(), back_rc);
|
||||
SaveRenderTarget(s_sScreenshotName.c_str(), dst_rect);
|
||||
// Reset settings
|
||||
s_sScreenshotName = "";
|
||||
s_bScreenshot = false;
|
||||
|
@ -1261,11 +1280,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
if (g_ActiveConfig.bDumpFrames)
|
||||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
int w = back_rc.GetWidth();
|
||||
int h = back_rc.GetHeight();
|
||||
int w = dst_rect.GetWidth();
|
||||
int h = dst_rect.GetHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(back_rc.left, back_rc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
|
||||
{
|
||||
if (!s_bLastFrameDumped)
|
||||
|
@ -1306,11 +1325,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
{
|
||||
s_criticalScreenshot.Enter();
|
||||
char movie_file_name[255];
|
||||
int w = back_rc.GetWidth();
|
||||
int h = back_rc.GetHeight();
|
||||
int w = dst_rect.GetWidth();
|
||||
int h = dst_rect.GetHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(back_rc.left, back_rc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
glReadPixels(dst_rect.left, dst_rect.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
if (GL_REPORT_ERROR() == GL_NO_ERROR)
|
||||
{
|
||||
if (!s_bLastFrameDumped)
|
||||
|
@ -1348,6 +1367,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
s_bLastFrameDumped = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finish up the current frame, print some stats
|
||||
OpenGL_Update(); // just updates the render window position and the backbuffer size
|
||||
bool xfbchanged = false;
|
||||
|
@ -1364,38 +1384,47 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
}
|
||||
|
||||
bool WindowResized = false;
|
||||
int W = (int)OpenGL_GetBackbufferWidth(), H = (int)OpenGL_GetBackbufferHeight();
|
||||
if (W != s_backbuffer_width || H != s_backbuffer_height)
|
||||
int W = (int)OpenGL_GetBackbufferWidth();
|
||||
int H = (int)OpenGL_GetBackbufferHeight();
|
||||
if (W != s_backbuffer_width || H != s_backbuffer_height || s_LastEFBScale != g_ActiveConfig.iEFBScale)
|
||||
{
|
||||
WindowResized = true;
|
||||
s_backbuffer_width = W;
|
||||
s_backbuffer_height = H;
|
||||
s_LastEFBScale = g_ActiveConfig.iEFBScale;
|
||||
}
|
||||
|
||||
if( xfbchanged || WindowResized)
|
||||
if (xfbchanged || WindowResized)
|
||||
{
|
||||
TargetRectangle dst_rect;
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
|
||||
if(!g_ActiveConfig.bNativeResolution)
|
||||
if(g_ActiveConfig.bUseRealXFB)
|
||||
{
|
||||
if (g_ActiveConfig.b2xResolution)
|
||||
{
|
||||
xScale = 2.0f;
|
||||
yScale = 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
xScale = 1.0f;
|
||||
yScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width;
|
||||
yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height;
|
||||
}
|
||||
|
||||
EFBxScale = ceilf(xScale);
|
||||
EFByScale = ceilf(yScale);
|
||||
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;
|
||||
};
|
||||
|
||||
int m_newFrameBufferWidth = EFB_WIDTH * EFBxScale;
|
||||
int m_newFrameBufferHeight = EFB_HEIGHT * EFByScale;
|
||||
|
@ -1405,6 +1434,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||
s_target_width = m_newFrameBufferWidth;
|
||||
s_target_height = m_newFrameBufferHeight;
|
||||
|
||||
s_Fulltarget_width = s_target_width;
|
||||
s_Fulltarget_height = s_target_height;
|
||||
|
||||
g_framebufferManager.Shutdown();
|
||||
g_framebufferManager.Init(s_target_width, s_target_height,
|
||||
s_MSAASamples, s_MSAACoverageSamples);
|
||||
|
@ -1617,23 +1649,6 @@ void Renderer::SetScreenshot(const char *filename)
|
|||
s_criticalScreenshot.Leave();
|
||||
}
|
||||
|
||||
// For the OSD menu's live resolution change
|
||||
bool Renderer::Allow2x()
|
||||
{
|
||||
if (GetFrameBufferWidth() >= 1280 && GetFrameBufferHeight() >= 960)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Renderer::AllowCustom()
|
||||
{
|
||||
if (GetCustomWidth() <= GetFrameBufferWidth() && GetCustomHeight() <= GetFrameBufferHeight())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderer::FlipImageData(u8 *data, int w, int h)
|
||||
{
|
||||
// Flip image upside down. Damn OpenGL.
|
||||
|
|
|
@ -500,7 +500,7 @@ TextureCache::TCacheEntry* TextureCache::Load(int texstage, u32 address, int wid
|
|||
}
|
||||
else
|
||||
{
|
||||
if(skip_texture_create)
|
||||
if (skip_texture_create)
|
||||
{
|
||||
glCompressedTexSubImage2D(target, 0,0,0,width, height,
|
||||
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,expandedWidth*expandedHeight/2, temp);
|
||||
|
|
|
@ -371,7 +371,6 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
|
|||
cacheBytes = 64;
|
||||
|
||||
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
|
||||
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
|
||||
TextureCache::MakeRangeDynamic(address,size_in_bytes);
|
||||
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
|
||||
|
@ -400,10 +399,10 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
|
|||
return;
|
||||
}
|
||||
|
||||
Renderer::ResetAPIState();
|
||||
|
||||
int srcFmtWidth = srcWidth / 2;
|
||||
|
||||
Renderer::ResetAPIState(); // reset any game specific settings
|
||||
|
||||
// swich to texture converter frame buffer
|
||||
// attach destTexture as color destination
|
||||
g_framebufferManager.SetFramebuffer(s_texConvFrameBuffer);
|
||||
|
|
|
@ -181,17 +181,17 @@ void AddVertices(int primitive, int numVertices)
|
|||
|
||||
inline void Draw()
|
||||
{
|
||||
if(IndexGenerator::GetNumTriangles() > 0)
|
||||
if (IndexGenerator::GetNumTriangles() > 0)
|
||||
{
|
||||
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
if(IndexGenerator::GetNumLines() > 0)
|
||||
if (IndexGenerator::GetNumLines() > 0)
|
||||
{
|
||||
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
}
|
||||
if(IndexGenerator::GetNumPoints() > 0)
|
||||
if (IndexGenerator::GetNumPoints() > 0)
|
||||
{
|
||||
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
|
||||
INCSTAT(stats.thisFrame.numIndexedDrawCalls);
|
||||
|
@ -288,26 +288,23 @@ void Flush()
|
|||
}
|
||||
}
|
||||
|
||||
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
|
||||
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
||||
|
||||
// set global constants
|
||||
VertexShaderManager::SetConstants();
|
||||
PixelShaderManager::SetConstants();
|
||||
|
||||
// finally bind
|
||||
|
||||
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
|
||||
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
|
||||
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
|
||||
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
|
||||
|
||||
Draw();
|
||||
|
||||
// run through vertex groups again to set alpha
|
||||
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||
if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
||||
{
|
||||
ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
|
||||
|
||||
if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||
|
||||
// only update alpha
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
|
@ -353,6 +350,5 @@ void Flush()
|
|||
g_Config.iSaveTargetId++;
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
|
|
@ -50,9 +50,9 @@ Make AA apply instantly during gameplay if possible
|
|||
*/
|
||||
|
||||
#include "Globals.h"
|
||||
#include "LogManager.h"
|
||||
#include "Thread.h"
|
||||
#include "Atomic.h"
|
||||
#include "Thread.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
|
@ -124,7 +124,15 @@ bool IsD3D()
|
|||
return false;
|
||||
}
|
||||
|
||||
void GetDllInfo (PLUGIN_INFO* _PluginInfo)
|
||||
// This is used for the functions right below here which use wxwidgets
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#ifdef _WIN32
|
||||
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
||||
extern HINSTANCE g_hInstance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void GetDllInfo(PLUGIN_INFO* _PluginInfo)
|
||||
{
|
||||
_PluginInfo->Version = 0x0100;
|
||||
_PluginInfo->Type = PLUGIN_TYPE_VIDEO;
|
||||
|
@ -143,14 +151,6 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
|
|||
LogManager::SetInstance((LogManager*)globals->logManager);
|
||||
}
|
||||
|
||||
// This is used for the functions right below here which use wxwidgets
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#ifdef _WIN32
|
||||
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
|
||||
extern HINSTANCE g_hInstance;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void *DllDebugger(void *_hParent, bool Show)
|
||||
{
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
|
@ -205,6 +205,68 @@ void Initialize(void *init)
|
|||
s_PluginInitialized = true;
|
||||
}
|
||||
|
||||
// This is called after Initialize() from the Core
|
||||
// Run from the graphics thread
|
||||
void Video_Prepare()
|
||||
{
|
||||
OpenGL_MakeCurrent();
|
||||
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
// internal interfaces
|
||||
Renderer::Init();
|
||||
TextureCache::Init();
|
||||
VertexManager::Init();
|
||||
BPInit();
|
||||
Fifo_Init();
|
||||
VertexLoaderManager::Init();
|
||||
OpcodeDecoder_Init();
|
||||
VertexShaderCache::Init();
|
||||
VertexShaderManager::Init();
|
||||
PixelShaderCache::Init();
|
||||
PixelShaderManager::Init();
|
||||
CommandProcessor::Init();
|
||||
PixelEngine::Init();
|
||||
PostProcessing::Init();
|
||||
TextureConverter::Init();
|
||||
DLCache::Init();
|
||||
|
||||
// Notify the core that the video plugin is ready
|
||||
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
||||
|
||||
s_PluginInitialized = true;
|
||||
INFO_LOG(VIDEO, "Video plugin initialized.");
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
s_PluginInitialized = false;
|
||||
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
// VideoCommon
|
||||
DLCache::Shutdown();
|
||||
Fifo_Shutdown();
|
||||
PostProcessing::Shutdown();
|
||||
CommandProcessor::Shutdown();
|
||||
PixelShaderManager::Shutdown();
|
||||
VertexShaderManager::Shutdown();
|
||||
OpcodeDecoder_Shutdown();
|
||||
VertexLoaderManager::Shutdown();
|
||||
PixelShaderCache::Shutdown();
|
||||
TextureConverter::Shutdown();
|
||||
VertexShaderCache::Shutdown();
|
||||
VertexManager::Shutdown();
|
||||
TextureCache::Shutdown();
|
||||
Renderer::Shutdown();
|
||||
OpenGL_Shutdown();
|
||||
EmuWindow::Close();
|
||||
}
|
||||
|
||||
static volatile struct
|
||||
{
|
||||
unsigned char **ptr;
|
||||
|
@ -260,73 +322,6 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
|
|||
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
|
||||
}
|
||||
|
||||
// This is called after Initialize() from the Core
|
||||
// Run from the graphics thread
|
||||
void Video_Prepare(void)
|
||||
{
|
||||
OpenGL_MakeCurrent();
|
||||
if (!Renderer::Init()) {
|
||||
g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
|
||||
PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
|
||||
CommandProcessor::Init();
|
||||
PixelEngine::Init();
|
||||
|
||||
TextureCache::Init();
|
||||
|
||||
BPInit();
|
||||
VertexManager::Init();
|
||||
Fifo_Init(); // must be done before OpcodeDecoder_Init()
|
||||
OpcodeDecoder_Init();
|
||||
VertexShaderCache::Init();
|
||||
VertexShaderManager::Init();
|
||||
PixelShaderCache::Init();
|
||||
PixelShaderManager::Init();
|
||||
PostProcessing::Init();
|
||||
GL_REPORT_ERRORD();
|
||||
VertexLoaderManager::Init();
|
||||
TextureConverter::Init();
|
||||
DLCache::Init();
|
||||
|
||||
// Notify the core that the video plugin is ready
|
||||
g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
|
||||
|
||||
s_PluginInitialized = true;
|
||||
INFO_LOG(VIDEO, "Video plugin initialized.");
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
s_PluginInitialized = false;
|
||||
|
||||
s_efbAccessRequested = FALSE;
|
||||
s_FifoShuttingDown = FALSE;
|
||||
s_swapRequested = FALSE;
|
||||
DLCache::Shutdown();
|
||||
Fifo_Shutdown();
|
||||
PostProcessing::Shutdown();
|
||||
|
||||
// The following calls are NOT Thread Safe
|
||||
// And need to be called from the video thread
|
||||
TextureConverter::Shutdown();
|
||||
VertexLoaderManager::Shutdown();
|
||||
VertexShaderCache::Shutdown();
|
||||
VertexShaderManager::Shutdown();
|
||||
PixelShaderManager::Shutdown();
|
||||
PixelShaderCache::Shutdown();
|
||||
VertexManager::Shutdown();
|
||||
TextureCache::Shutdown();
|
||||
OpcodeDecoder_Shutdown();
|
||||
Renderer::Shutdown();
|
||||
OpenGL_Shutdown();
|
||||
}
|
||||
|
||||
// Enter and exit the video loop
|
||||
void Video_EnterLoop()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue