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:
skidau 2010-09-30 15:24:34 +00:00
parent ce1057f17d
commit 719521eeeb
25 changed files with 423 additions and 450 deletions

View File

@ -59,9 +59,6 @@ public:
static void SetLineWidth(); static void SetLineWidth();
static void SetSamplerState(int stage,int texindex); static void SetSamplerState(int stage,int texindex);
static void SetInterlacingMode(); static void SetInterlacingMode();
// Live resolution change
static bool Allow2x();
static bool AllowCustom();
// Render target management // Render target management
static int GetFrameBufferWidth(); static int GetFrameBufferWidth();

View File

@ -48,14 +48,11 @@ void VideoConfig::Load(const char *ini_file)
iniFile.Load(ini_file); iniFile.Load(ini_file);
iniFile.Get("Hardware", "VSync", &bVSync, 0); // Hardware 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", "wideScreenHack", &bWidescreenHack, false);
iniFile.Get("Settings", "AspectRatio", &iAspectRatio, (int)ASPECT_AUTO); iniFile.Get("Settings", "AspectRatio", &iAspectRatio, (int)ASPECT_AUTO);
iniFile.Get("Settings", "Crop", &bCrop, false); iniFile.Get("Settings", "Crop", &bCrop, false);
iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); iniFile.Get("Settings", "UseXFB", &bUseXFB, 0);
iniFile.Get("Settings", "UseRealXFB", &bUseRealXFB, 0); iniFile.Get("Settings", "UseRealXFB", &bUseRealXFB, 0);
iniFile.Get("Settings", "AutoScale", &bAutoScale, true);
iniFile.Get("Settings", "UseNativeMips", &bUseNativeMips, true); iniFile.Get("Settings", "UseNativeMips", &bUseNativeMips, true);
iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings
@ -165,14 +162,11 @@ void VideoConfig::Save(const char *ini_file)
IniFile iniFile; IniFile iniFile;
iniFile.Load(ini_file); iniFile.Load(ini_file);
iniFile.Set("Hardware", "VSync", bVSync); iniFile.Set("Hardware", "VSync", bVSync);
iniFile.Set("Settings", "StretchToFit", bNativeResolution);
iniFile.Set("Settings", "2xResolution", b2xResolution);
iniFile.Set("Settings", "AspectRatio", iAspectRatio); iniFile.Set("Settings", "AspectRatio", iAspectRatio);
iniFile.Set("Settings", "Crop", bCrop); iniFile.Set("Settings", "Crop", bCrop);
iniFile.Set("Settings", "wideScreenHack", bWidescreenHack); iniFile.Set("Settings", "wideScreenHack", bWidescreenHack);
iniFile.Set("Settings", "UseXFB", bUseXFB); iniFile.Set("Settings", "UseXFB", bUseXFB);
iniFile.Set("Settings", "UseRealXFB", bUseRealXFB); iniFile.Set("Settings", "UseRealXFB", bUseRealXFB);
iniFile.Set("Settings", "AutoScale", bAutoScale);
iniFile.Set("Settings", "UseNativeMips", bUseNativeMips); iniFile.Set("Settings", "UseNativeMips", bUseNativeMips);
iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache);

View File

@ -69,13 +69,12 @@ struct VideoConfig
// General // General
bool bVSync; bool bVSync;
bool bNativeResolution, b2xResolution, bRunning; // Should possibly be augmented with 2x, 4x native. bool bRunning;
bool bWidescreenHack; bool bWidescreenHack;
int iAspectRatio; int iAspectRatio;
bool bCrop; // Aspect ratio controls. bool bCrop; // Aspect ratio controls.
bool bUseXFB; bool bUseXFB;
bool bUseRealXFB; bool bUseRealXFB;
bool bAutoScale; // Removes annoying borders without using XFB. Doesn't always work perfectly.
bool bUseNativeMips; bool bUseNativeMips;
// OpenCL // OpenCL

View File

@ -924,17 +924,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
drawRc.left = -(xfbWidth / (float)fbWidth); drawRc.left = -(xfbWidth / (float)fbWidth);
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = (xfbWidth / (float)fbWidth);
if (!g_ActiveConfig.bAutoScale) // The following code disables auto stretch. Kept for reference.
{ // scale draw area for a 1 to 1 pixel mapping with the draw target
// scale draw area for a 1 to 1 pixel mapping with the draw target //float vScale = (float)fbHeight / (float)s_backbuffer_height;
float vScale = (float)fbHeight / (float)s_backbuffer_height; //float hScale = (float)fbWidth / (float)s_backbuffer_width;
float hScale = (float)fbWidth / (float)s_backbuffer_width; //drawRc.top *= vScale;
//drawRc.bottom *= vScale;
drawRc.top *= vScale; //drawRc.left *= hScale;
drawRc.bottom *= vScale; //drawRc.right *= hScale;
drawRc.left *= hScale;
drawRc.right *= hScale;
}
} }
else else
{ {

View File

@ -59,7 +59,7 @@ void SetLineWidth(const BPCmd &bp)
void SetDepthMode(const BPCmd &bp) void SetDepthMode(const BPCmd &bp)
{ {
Renderer::SetDepthMode(); Renderer::SetDepthMode();
} }
void SetBlendMode(const BPCmd &bp) void SetBlendMode(const BPCmd &bp)

View File

@ -210,9 +210,9 @@ void GFXConfigDialogDX::CreateGUIControls()
arrayStringFor_MSAAModeCB.Add(wxString::FromAscii(adapter.aa_levels[i].name)); 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_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 ); 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 ); int m_EFBScaleModeNChoices = sizeof( m_EFBScaleModeChoices ) / sizeof( wxString );
m_EFBScaleMode = new wxChoice( m_PageDirect3D, ID_EFBSCALEMODE, wxDefaultPosition, wxDefaultSize, m_EFBScaleModeNChoices, m_EFBScaleModeChoices, 0 ); m_EFBScaleMode = new wxChoice( m_PageDirect3D, ID_EFBSCALEMODE, wxDefaultPosition, wxDefaultSize, m_EFBScaleModeNChoices, m_EFBScaleModeChoices, 0 );

View File

@ -145,8 +145,8 @@ void OSDMenu(WPARAM wParam)
case '3': case '3':
OSDChoice = 1; OSDChoice = 1;
// Toggle native resolution // Toggle native resolution
OSDInternalW = D3D::GetBackBufferWidth(); g_Config.iEFBScale = g_Config.iEFBScale + 1;
OSDInternalH = D3D::GetBackBufferHeight(); if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
break; break;
case '4': case '4':
OSDChoice = 2; OSDChoice = 2;

View File

@ -276,7 +276,7 @@ void PixelShaderCache::Shutdown()
bool PixelShaderCache::SetShader(bool dstAlpha,u32 components) bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
{ {
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlpha); GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
// Check if the shader is already set // Check if the shader is already set
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount) if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)

View File

@ -308,7 +308,8 @@ bool Renderer::Init()
if(g_ActiveConfig.bUseRealXFB) if(g_ActiveConfig.bUseRealXFB)
{ {
xScale = yScale = 1.0f; xScale = 1.0f;
yScale = 1.0f;
} }
else else
{ {
@ -438,21 +439,10 @@ float Renderer::GetXFBScaleY()
return yScale; return yScale;
} }
// Return the framebuffer size
int Renderer::GetFrameBufferWidth()
{
return s_backbuffer_width;
}
int Renderer::GetFrameBufferHeight()
{
return s_backbuffer_height;
}
// Create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugText() void Renderer::DrawDebugText()
{ {
// OSD menu messages // OSD Menu messages
if (g_ActiveConfig.bOSDHotKey) if (g_ActiveConfig.bOSDHotKey)
{ {
if (OSDChoice > 0) if (OSDChoice > 0)
@ -465,7 +455,26 @@ void Renderer::DrawDebugText()
std::string T1 = "", T2 = ""; std::string T1 = "", T2 = "";
std::vector<std::string> T0; 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; std::string OSDM21;
switch(g_ActiveConfig.iAspectRatio) 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 Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{ {
TargetRectangle result;
int Xstride = (s_Fulltarget_width - s_target_width) / 2; int Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2; int Ystride = (s_Fulltarget_height - s_target_height) / 2;
TargetRectangle result;
result.left = (int)(rc.left * EFBxScale) + Xstride; result.left = (int)(rc.left * EFBxScale) + Xstride;
result.top = (int)(rc.top * EFByScale) + Ystride; result.top = (int)(rc.top * EFByScale) + Ystride;
result.right = (int)(rc.right * EFBxScale) + Xstride; result.right = (int)(rc.right * EFBxScale) + Xstride;
@ -654,6 +663,7 @@ bool Renderer::SetScissorRect()
rc.right = (int)(rc.right * EFBxScale) + Xstride; rc.right = (int)(rc.right * EFBxScale) + Xstride;
rc.bottom = (int)(rc.bottom * EFByScale) + Ystride; rc.bottom = (int)(rc.bottom * EFByScale) + Ystride;
// Check that the coordinates are good
if (rc.right != rc.left && rc.bottom != rc.top) if (rc.right != rc.left && rc.bottom != rc.top)
{ {
D3D::dev->SetScissorRect(&rc); D3D::dev->SetScissorRect(&rc);
@ -727,7 +737,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
efbPixelRc.right = x + 1; efbPixelRc.right = x + 1;
efbPixelRc.bottom = y + 1; efbPixelRc.bottom = y + 1;
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc); TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc);
u32 z = 0; u32 z = 0;
float val = 0.0f; float val = 0.0f;
@ -897,19 +907,16 @@ void UpdateViewport()
int scissorXOff = bpmem.scissorOffset.x * 2; int scissorXOff = bpmem.scissorOffset.x * 2;
int scissorYOff = bpmem.scissorOffset.y * 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 Xstride = (s_Fulltarget_width - s_target_width) / 2;
int Ystride = (s_Fulltarget_height - s_target_height) / 2; int Ystride = (s_Fulltarget_height - s_target_height) / 2;
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
// Stretch picture with increased internal resolution // Stretch picture with increased internal resolution
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * MValueX) + Xstride; int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * EFBxScale) + Xstride;
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY) + Ystride; int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * EFByScale) + Ystride;
int Width = (int)ceil((int)(2 * xfregs.rawViewport[0]) * MValueX); int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * MValueY); int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
if (Width < 0) if (Width < 0)
{ {
X += Width; X += Width;
@ -988,7 +995,7 @@ void UpdateViewport()
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
{ {
// Update the view port for clearing the picture // Update the view port for clearing the picture
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
vp.X = targetRc.left; vp.X = targetRc.left;
vp.Y = targetRc.top; vp.Y = targetRc.top;
@ -1062,7 +1069,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
return; return;
} }
Renderer::ResetAPIState(); ResetAPIState();
if(g_ActiveConfig.bAnaglyphStereo) if(g_ActiveConfig.bAnaglyphStereo)
{ {
if(RightFrame) if(RightFrame)
@ -1090,6 +1097,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
TargetRectangle dst_rect; TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
// Clear full target screen (edges, borders etc)
vp.X = 0; vp.X = 0;
vp.Y = 0; vp.Y = 0;
vp.Width = s_backbuffer_width; vp.Width = s_backbuffer_width;
@ -1104,7 +1113,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
int Y = dst_rect.top; int Y = dst_rect.top;
int Width = dst_rect.right - dst_rect.left; int Width = dst_rect.right - dst_rect.left;
int Height = dst_rect.bottom - dst_rect.top; int Height = dst_rect.bottom - dst_rect.top;
// Sanity check
if (X < 0) X = 0; if (X < 0) X = 0;
if (Y < 0) Y = 0; if (Y < 0) Y = 0;
if (X > s_backbuffer_width) X = s_backbuffer_width; 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 (Height < 0) Height = 0;
if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X;
if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y;
vp.X = X; vp.X = X;
vp.Y = Y; vp.Y = Y;
vp.Width = Width; 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_MINFILTER, D3DTEXF_LINEAR);
D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
const XFBSource* xfbSource = NULL;
if(g_ActiveConfig.bUseXFB) if(g_ActiveConfig.bUseXFB)
{ {
const XFBSource* xfbSource;
// draw each xfb source // draw each xfb source
// Render to the real buffer now.
for (u32 i = 0; i < xfbCount; ++i) for (u32 i = 0; i < xfbCount; ++i)
{ {
xfbSource = xfbSourceList[i]; xfbSource = xfbSourceList[i];
MathUtil::Rectangle<float> sourceRc; MathUtil::Rectangle<float> sourceRc;
sourceRc.left = 0; sourceRc.left = 0;
@ -1142,7 +1155,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) if (!g_ActiveConfig.bUseRealXFB)
{ {
// use virtual xfb with offset // use virtual xfb with offset
int xfbHeight = xfbSource->srcHeight; 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.left = -(xfbWidth / (float)fbWidth);
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = (xfbWidth / (float)fbWidth);
if (!g_ActiveConfig.bAutoScale) // The following code disables auto stretch. Kept for reference.
{ // scale draw area for a 1 to 1 pixel mapping with the draw target
// scale draw area for a 1 to 1 pixel mapping with the draw target //float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
float vScale = (float)fbHeight / (float)s_backbuffer_height; //float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
float hScale = (float)fbWidth / (float)s_backbuffer_width; //drawRc.top *= vScale;
//drawRc.bottom *= vScale;
drawRc.top *= vScale; //drawRc.left *= hScale;
drawRc.bottom *= vScale; //drawRc.right *= hScale;
drawRc.left *= hScale;
drawRc.right *= hScale;
}
} }
else else
{ {
@ -1179,17 +1189,19 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
else else
{ {
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(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::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_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
if(g_ActiveConfig.bAnaglyphStereo) if(g_ActiveConfig.bAnaglyphStereo)
{ {
DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
} }
vp.X = 0; vp.X = 0;
vp.Y = 0; vp.Y = 0;
vp.Width = s_backbuffer_width; 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.MinZ = 0.0f;
vp.MaxZ = 1.0f; vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp); D3D::dev->SetViewport(&vp);
// Save screenshot
if (s_bScreenshot) if (s_bScreenshot)
{ {
s_criticalScreenshot.Enter(); 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 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_LastAA = newAA;
s_LastEFBScale = newEFBScale;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
if(g_ActiveConfig.bUseRealXFB) if(g_ActiveConfig.bUseRealXFB)
{ {
xScale = yScale = 1.0f; xScale = 1.0f;
yScale = 1.0f;
} }
else else
{ {
@ -1321,6 +1335,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
float SupersampleCoeficient = s_LastAA + 1; float SupersampleCoeficient = s_LastAA + 1;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
switch(s_LastEFBScale) switch(s_LastEFBScale)
{ {
case 0: case 0:
@ -1339,8 +1354,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
EFBxScale *= SupersampleCoeficient; EFBxScale *= SupersampleCoeficient;
EFByScale *= SupersampleCoeficient; EFByScale *= SupersampleCoeficient;
s_target_width = EFB_WIDTH * EFBxScale; s_target_width = EFB_WIDTH * EFBxScale;
s_target_height = EFB_HEIGHT * EFByScale; s_target_height = EFB_HEIGHT * EFByScale;
s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height;
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
if (WindowResized) if (WindowResized)
@ -1379,7 +1399,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// Flip/present backbuffer to frontbuffer here // Flip/present backbuffer to frontbuffer here
D3D::Present(); D3D::Present();
D3D::BeginFrame(); D3D::BeginFrame();
Renderer::RestoreAPIState(); RestoreAPIState();
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
UpdateViewport(); UpdateViewport();

View File

@ -305,36 +305,6 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
if (pcfmt == PC_TEX_FMT_NONE) if (pcfmt == PC_TEX_FMT_NONE)
pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt); 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]; entry.oldpixel = ((u32 *)ptr)[0];
if (g_ActiveConfig.bSafeTextureCache || entry.isDynamic) if (g_ActiveConfig.bSafeTextureCache || entry.isDynamic)
entry.hash = hash_value; entry.hash = hash_value;
@ -354,6 +324,40 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
if(TexLevels > (maxlevel + 1) && maxlevel > 0) if(TexLevels > (maxlevel + 1) && maxlevel > 0)
TexLevels = (maxlevel + 1); TexLevels = (maxlevel + 1);
entry.MipLevels = maxlevel; 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) if (!skip_texture_create)
{ {
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b, TexLevels); entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt, swap_r_b, TexLevels);

View File

@ -376,7 +376,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
} }
u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 SourceW, u32 SourceH,float MValueX,float MValueY,float Xstride, float Ystride , bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
@ -437,11 +437,9 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
cacheBytes = 64; cacheBytes = 64;
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); 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); TextureCache::MakeRangeDynamic(address,size_in_bytes);
u64 Hashvalue = 0; return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
Hashvalue = GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
return Hashvalue;
} }
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
@ -474,7 +472,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
} }
int srcFmtWidth = srcWidth / 2; int srcFmtWidth = srcWidth / 2;
Renderer::ResetAPIState(); // reset any game specific settings Renderer::ResetAPIState(); // reset any game specific settings
LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false); LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false);
LPDIRECT3DSURFACE9 Rendersurf = NULL; LPDIRECT3DSURFACE9 Rendersurf = NULL;

View File

@ -197,7 +197,7 @@ GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) cons
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
// required. // required.
TargetRectangle targetRc = ConvertEFBRectangle(sourceRc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
@ -227,7 +227,7 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) cons
// Transfer the EFB to a resolved texture. EXT_framebuffer_blit is // Transfer the EFB to a resolved texture. EXT_framebuffer_blit is
// required. // required.
TargetRectangle targetRc = ConvertEFBRectangle(sourceRc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(sourceRc);
targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight); targetRc.ClampLL(0, 0, m_targetWidth, m_targetHeight);
// Resolve. // Resolve.
@ -262,18 +262,6 @@ const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); 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) FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
{ {
u32 srcLower = xfbAddr; u32 srcLower = xfbAddr;
@ -373,7 +361,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
it->xfbSource.texWidth = Renderer::GetTargetWidth(); it->xfbSource.texWidth = Renderer::GetTargetWidth();
it->xfbSource.texHeight = Renderer::GetTargetHeight(); it->xfbSource.texHeight = Renderer::GetTargetHeight();
it->xfbSource.sourceRc = ConvertEFBRectangle(sourceRc); it->xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
xfbTexture = it->xfbSource.texture; xfbTexture = it->xfbSource.texture;
@ -417,7 +405,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
newVirt.xfbSource.texture = xfbTexture; newVirt.xfbSource.texture = xfbTexture;
newVirt.xfbSource.texWidth = m_targetWidth; newVirt.xfbSource.texWidth = m_targetWidth;
newVirt.xfbSource.texHeight = m_targetHeight; newVirt.xfbSource.texHeight = m_targetHeight;
newVirt.xfbSource.sourceRc = ConvertEFBRectangle(sourceRc); newVirt.xfbSource.sourceRc = Renderer::ConvertEFBRectangle(sourceRc);
// Add the new Virtual XFB to the list // Add the new Virtual XFB to the list

View File

@ -106,8 +106,6 @@ public:
// Resolved framebuffer is only used in MSAA mode. // Resolved framebuffer is only used in MSAA mode.
GLuint GetResolvedFramebuffer() const { return m_resolvedFramebuffer; } GLuint GetResolvedFramebuffer() const { return m_resolvedFramebuffer; }
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc) const;
void SetFramebuffer(GLuint fb); 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. // If in MSAA mode, this will perform a resolve of the specified rectangle, and return the resolve target as a texture ID.

View File

@ -164,16 +164,8 @@ THREAD_RETURN XEventThread(void *pArg)
case XK_3: case XK_3:
OSDChoice = 1; OSDChoice = 1;
// Toggle native resolution // Toggle native resolution
if (!(g_Config.bNativeResolution || g_Config.b2xResolution)) g_Config.iEFBScale = g_Config.iEFBScale + 1;
g_Config.bNativeResolution = true; if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
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;
break; break;
case XK_4: case XK_4:
OSDChoice = 2; OSDChoice = 2;

View File

@ -39,14 +39,12 @@ BEGIN_EVENT_TABLE(GFXConfigDialogOGL,wxDialog)
EVT_CHECKBOX(ID_VSYNC, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_VSYNC, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHOICE(ID_MAXANISOTROPY, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHOICE(ID_MAXANISOTROPY, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHOICE(ID_MSAAMODECB, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHOICE(ID_MSAAMODECB, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_NATIVERESOLUTION, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHOICE(ID_EFBSCALEMODE, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_2X_RESOLUTION, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_USEXFB, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_USEXFB, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_USEREALXFB, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_USEREALXFB, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_FORCEFILTERING, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_FORCEFILTERING, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_USENATIVEMIPS, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_USENATIVEMIPS, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_EFBSCALEDCOPY, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_EFBSCALEDCOPY, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_AUTOSCALE, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_WIDESCREENHACK, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_WIDESCREENHACK, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHOICE(ID_ASPECT, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHOICE(ID_ASPECT, GFXConfigDialogOGL::GeneralSettingsChanged)
EVT_CHECKBOX(ID_CROP, GFXConfigDialogOGL::GeneralSettingsChanged) EVT_CHECKBOX(ID_CROP, GFXConfigDialogOGL::GeneralSettingsChanged)
@ -154,6 +152,13 @@ void GFXConfigDialogOGL::LoadShaders()
void GFXConfigDialogOGL::InitializeGUILists() 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 // Keep Aspect Ratio
arrayStringFor_AspectRatio.Add(wxT("Auto Aspect (recommended)")); arrayStringFor_AspectRatio.Add(wxT("Auto Aspect (recommended)"));
arrayStringFor_AspectRatio.Add(wxT("Force 16:9 Widescreen")); arrayStringFor_AspectRatio.Add(wxT("Force 16:9 Widescreen"));
@ -191,8 +196,7 @@ void GFXConfigDialogOGL::InitializeGUILists()
void GFXConfigDialogOGL::InitializeGUIValues() void GFXConfigDialogOGL::InitializeGUIValues()
{ {
// General Display Settings // General Display Settings
m_NativeResolution->SetValue(g_Config.bNativeResolution); m_EFBScaleMode->SetSelection(g_Config.iEFBScale);
m_2xResolution->SetValue(g_Config.b2xResolution);
m_KeepAR->SetSelection(g_Config.iAspectRatio); m_KeepAR->SetSelection(g_Config.iAspectRatio);
m_Crop->SetValue(g_Config.bCrop); m_Crop->SetValue(g_Config.bCrop);
@ -202,7 +206,6 @@ void GFXConfigDialogOGL::InitializeGUIValues()
m_VSync->SetValue(g_Config.bVSync); m_VSync->SetValue(g_Config.bVSync);
m_UseXFB->SetValue(g_Config.bUseXFB); m_UseXFB->SetValue(g_Config.bUseXFB);
m_UseRealXFB->SetValue(g_Config.bUseRealXFB); m_UseRealXFB->SetValue(g_Config.bUseRealXFB);
m_AutoScale->SetValue(g_Config.bAutoScale);
m_WidescreenHack->SetValue(g_Config.bWidescreenHack); m_WidescreenHack->SetValue(g_Config.bWidescreenHack);
m_UseNativeMips->SetValue(g_Config.bUseNativeMips); m_UseNativeMips->SetValue(g_Config.bUseNativeMips);
m_EFBScaledCopy->SetValue(g_Config.bCopyEFBScaled); m_EFBScaledCopy->SetValue(g_Config.bCopyEFBScaled);
@ -260,14 +263,12 @@ void GFXConfigDialogOGL::InitializeGUIValues()
void GFXConfigDialogOGL::InitializeGUITooltips() void GFXConfigDialogOGL::InitializeGUITooltips()
{ {
// Tool tips // Tool tips
m_NativeResolution->SetToolTip( m_EFBScaleMode->SetToolTip(
wxT("This will use the game's native resolution and stretch it to fill the") wxT("This will change the game's native resolution and stretch it to fill the")
wxT("\nwindow instead of changing the internal display resolution. It") wxT("\nwindow instead of changing the display resolution. It")
wxT("\nmay result in a blurrier image, but it may also give a higher") wxT("\nmay result in a blurrier image, but it may also give a higher")
wxT("\nFPS if you have a slow graphics card.") wxT("\nFPS if you have a slow graphics card.")
wxT("\n\nApplies instanty during gameplay: <Yes>")); wxT("\n\nApplies instantly during gameplay: <Yes>"));
m_2xResolution->SetToolTip(wxT(
"Applies instanty during gameplay: <Yes, if allowed>"));
m_KeepAR->SetToolTip( m_KeepAR->SetToolTip(
wxT("This sets the aspect ratio of the image.") wxT("This sets the aspect ratio of the image.")
wxT("\nThe Widescreen hack may cause graphical issues in some games !") wxT("\nThe Widescreen hack may cause graphical issues in some games !")
@ -358,9 +359,8 @@ void GFXConfigDialogOGL::CreateGUIControls()
// General Display Settings // General Display Settings
sbBasic = new wxStaticBoxSizer(wxVERTICAL, m_PageGeneral, wxT("Basic 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); wxStaticText *IRText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Internal Resolution:"), wxDefaultPosition, wxDefaultSize, 0);
m_NativeResolution = new wxCheckBox(m_PageGeneral, ID_NATIVERESOLUTION, wxT("Native"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_EFBScaleMode = new wxChoice(m_PageGeneral, ID_EFBSCALEMODE, wxDefaultPosition, wxDefaultSize, arrayStringFor_EFBScale);
m_2xResolution = new wxCheckBox(m_PageGeneral, ID_2X_RESOLUTION, wxT("2x"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Aspect ratio / positioning controls // Aspect ratio / positioning controls
wxStaticText *KeepARText = new wxStaticText(m_PageGeneral, wxID_ANY, wxT("Keep aspect ratio:"), wxDefaultPosition, wxDefaultSize, 0); 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); 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_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_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_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_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_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); 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 = new wxGridBagSizer(0, 0);
sBasic->Add(IRText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5); 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_EFBScaleMode, wxGBPosition(0, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(m_2xResolution, wxGBPosition(0, 2), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | wxALL, 5);
sBasic->Add(KeepARText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL | 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); 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_VSync, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
sBasicAdvanced->Add(m_UseXFB, wxGBPosition(2, 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_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_WidescreenHack, wxGBPosition(5, 0), wxGBSpan(1, 2), wxALL, 5);
sBasicAdvanced->Add(m_UseNativeMips, wxGBPosition(6, 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); sBasicAdvanced->Add(m_EFBScaledCopy, wxGBPosition(7, 0), wxGBSpan(1, 2), wxALL, 5);
@ -589,15 +586,9 @@ void GFXConfigDialogOGL::GeneralSettingsChanged(wxCommandEvent& event)
{ {
switch (event.GetId()) switch (event.GetId())
{ {
case ID_NATIVERESOLUTION: case ID_EFBSCALEMODE:
g_Config.bNativeResolution = m_NativeResolution->IsChecked(); g_Config.iEFBScale = m_EFBScaleMode->GetSelection();
// 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); }
break; break;
case ID_VSYNC: case ID_VSYNC:
g_Config.bVSync = m_VSync->IsChecked(); g_Config.bVSync = m_VSync->IsChecked();
@ -614,9 +605,6 @@ void GFXConfigDialogOGL::GeneralSettingsChanged(wxCommandEvent& event)
case ID_EFBSCALEDCOPY: case ID_EFBSCALEDCOPY:
g_Config.bCopyEFBScaled = m_EFBScaledCopy->IsChecked(); g_Config.bCopyEFBScaled = m_EFBScaledCopy->IsChecked();
break; break;
case ID_AUTOSCALE:
g_Config.bAutoScale = m_AutoScale->IsChecked();
break;
case ID_ASPECT: case ID_ASPECT:
g_Config.iAspectRatio = m_KeepAR->GetSelection(); g_Config.iAspectRatio = m_KeepAR->GetSelection();
break; break;
@ -775,20 +763,14 @@ void GFXConfigDialogOGL::UpdateGUI()
m_UseXFB->SetValue(true); m_UseXFB->SetValue(true);
// XFB looks much better if the copy comes from native resolution. // XFB looks much better if the copy comes from native resolution.
g_Config.bNativeResolution = true; g_Config.iEFBScale = 2;
m_NativeResolution->SetValue(true); m_EFBScaleMode->SetSelection(g_Config.iEFBScale);
//also disable 2x, since it might leave both checked.
g_Config.b2xResolution = false;
m_2xResolution->SetValue(false);
} }
m_AutoScale->Enable(!g_Config.bUseRealXFB);
m_UseXFB->Enable(!g_Config.bUseRealXFB); m_UseXFB->Enable(!g_Config.bUseRealXFB);
// Resolution settings // Resolution settings
//disable native/2x choice when real xfb is on. native simply looks best, as ector noted above. m_EFBScaleMode->Enable(!g_Config.bUseRealXFB);
//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()));
// Disable the Copy to options when EFBCopy is disabled // Disable the Copy to options when EFBCopy is disabled
m_Radio_CopyEFBToRAM->Enable(!(g_Config.bEFBCopyDisable)); m_Radio_CopyEFBToRAM->Enable(!(g_Config.bEFBCopyDisable));

View File

@ -90,7 +90,7 @@ class GFXConfigDialogOGL : public wxDialog
wxPanel *m_PageGeneral; wxPanel *m_PageGeneral;
wxPanel *m_PageAdvanced; wxPanel *m_PageAdvanced;
wxCheckBox *m_VSync; wxCheckBox *m_VSync;
wxCheckBox *m_NativeResolution, *m_2xResolution; wxChoice *m_EFBScaleMode;
wxCheckBox *m_WidescreenHack; wxCheckBox *m_WidescreenHack;
wxCheckBox *m_ForceFiltering; wxCheckBox *m_ForceFiltering;
wxCheckBox *m_Crop; wxCheckBox *m_Crop;
@ -98,7 +98,6 @@ class GFXConfigDialogOGL : public wxDialog
wxCheckBox *m_UseNativeMips; wxCheckBox *m_UseNativeMips;
wxCheckBox *m_EFBScaledCopy; wxCheckBox *m_EFBScaledCopy;
wxCheckBox *m_UseRealXFB; wxCheckBox *m_UseRealXFB;
wxCheckBox *m_AutoScale;
wxChoice *m_MaxAnisotropyCB; wxChoice *m_MaxAnisotropyCB;
wxChoice *m_MSAAModeCB, *m_PhackvalueCB, *m_PostShaderCB, *m_KeepAR; wxChoice *m_MSAAModeCB, *m_PhackvalueCB, *m_PostShaderCB, *m_KeepAR;
@ -136,6 +135,7 @@ class GFXConfigDialogOGL : public wxDialog
wxCheckBox *m_ScreenSize; wxCheckBox *m_ScreenSize;
wxArrayString arrayStringFor_FullscreenCB; wxArrayString arrayStringFor_FullscreenCB;
wxArrayString arrayStringFor_EFBScale;
wxArrayString arrayStringFor_AspectRatio; wxArrayString arrayStringFor_AspectRatio;
wxArrayString arrayStringFor_MaxAnisotropyCB; wxArrayString arrayStringFor_MaxAnisotropyCB;
wxArrayString arrayStringFor_MSAAModeCB; wxArrayString arrayStringFor_MSAAModeCB;
@ -149,14 +149,13 @@ class GFXConfigDialogOGL : public wxDialog
ID_PAGEADVANCED, ID_PAGEADVANCED,
ID_VSYNC, ID_VSYNC,
ID_NATIVERESOLUTION, ID_2X_RESOLUTION, ID_EFBSCALEMODE,
ID_ASPECT, ID_ASPECT,
ID_CROP, ID_CROP,
ID_USEREALXFB, ID_USEREALXFB,
ID_USEXFB, ID_USEXFB,
ID_USENATIVEMIPS, ID_USENATIVEMIPS,
ID_EFBSCALEDCOPY, ID_EFBSCALEDCOPY,
ID_AUTOSCALE,
ID_WIDESCREENHACK, ID_WIDESCREENHACK,
ID_FORCEFILTERING, ID_FORCEFILTERING,

View File

@ -123,7 +123,7 @@ void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
} }
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (_vtx_decl.color_offset[i] != -1) if (_vtx_decl.color_offset[i] != -1)
{ {

View File

@ -89,12 +89,8 @@ void OSDMenu(WPARAM wParam)
case '3': case '3':
OSDChoice = 1; OSDChoice = 1;
// Toggle native resolution // Toggle native resolution
if (!(g_Config.bNativeResolution || g_Config.b2xResolution)) g_Config.iEFBScale = g_Config.iEFBScale + 1;
g_Config.bNativeResolution = true; if (g_Config.iEFBScale > 4) g_Config.iEFBScale = 0;
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;
break; break;
case '4': case '4':
OSDChoice = 2; OSDChoice = 2;

View File

@ -35,7 +35,7 @@
static int s_nMaxPixelInstructions; static int s_nMaxPixelInstructions;
static GLuint s_ColorMatrixProgram = 0; static GLuint s_ColorMatrixProgram = 0;
static GLuint s_DepthMatrixProgram = 0; static GLuint s_DepthMatrixProgram = 0;
PixelShaderCache::PSCache PixelShaderCache::pshaders; PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
PIXELSHADERUID PixelShaderCache::s_curuid; PIXELSHADERUID PixelShaderCache::s_curuid;
bool PixelShaderCache::s_displayCompileAlert; bool PixelShaderCache::s_displayCompileAlert;
GLuint PixelShaderCache::CurrentShader; GLuint PixelShaderCache::CurrentShader;
@ -177,27 +177,30 @@ void PixelShaderCache::Shutdown()
s_ColorMatrixProgram = 0; s_ColorMatrixProgram = 0;
glDeleteProgramsARB(1, &s_DepthMatrixProgram); glDeleteProgramsARB(1, &s_DepthMatrixProgram);
s_DepthMatrixProgram = 0; s_DepthMatrixProgram = 0;
PSCache::iterator iter = pshaders.begin(); PSCache::iterator iter = PixelShaders.begin();
for (; iter != pshaders.end(); iter++) for (; iter != PixelShaders.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
pshaders.clear(); PixelShaders.clear();
} }
FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components) FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlpha,u32 components)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlphaEnable ? 1 : 0); GetPixelShaderId(&uid, dstAlpha ? 1 : 0);
if (uid == last_pixel_shader_uid && pshaders[uid].frameCount == frameCount)
// Check if the shader is already set
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
{ {
return pShaderLast; return pShaderLast;
} }
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID)); 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; iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second; PSCacheEntry &entry = iter->second;
if (&entry.shader != pShaderLast) if (&entry.shader != pShaderLast)
@ -209,10 +212,10 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
} }
//Make an entry in the table //Make an entry in the table
PSCacheEntry& newentry = pshaders[uid]; PSCacheEntry& newentry = PixelShaders[uid];
newentry.frameCount = frameCount; newentry.frameCount = frameCount;
pShaderLast = &newentry.shader; 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 defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
@ -235,7 +238,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
} }
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, pshaders.size()); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
return pShaderLast; return pShaderLast;
} }

View File

@ -57,7 +57,7 @@ class PixelShaderCache
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache; 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) static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written)

View File

@ -94,6 +94,7 @@ static int s_MSAACoverageSamples = 0;
bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp bool s_bHaveFramebufferBlit = false; // export to FramebufferManager.cpp
static bool s_bHaveCoverageMSAA = false; static bool s_bHaveCoverageMSAA = false;
static u32 s_blendMode; static u32 s_blendMode;
static u32 s_LastEFBScale;
static volatile bool s_bScreenshot = false; static volatile bool s_bScreenshot = false;
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
@ -105,6 +106,9 @@ static std::string s_sScreenshotName;
int frameCount; int frameCount;
// The custom resolution // 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. // TODO: Add functionality to reinit all the render targets when the window is resized.
static int s_backbuffer_width; static int s_backbuffer_width;
static int s_backbuffer_height; static int s_backbuffer_height;
@ -348,29 +352,40 @@ bool Renderer::Init()
TargetRectangle dst_rect; TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
xScale = 1.0f; if(g_ActiveConfig.bUseRealXFB)
yScale = 1.0f;
if(!g_ActiveConfig.bNativeResolution)
{ {
if (g_ActiveConfig.b2xResolution) xScale = 1.0f;
{ yScale = 1.0f;
xScale = 2.0f; }
yScale = 2.0f; else
} {
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 = (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); s_LastEFBScale = g_ActiveConfig.iEFBScale;
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;
};
s_target_width = EFB_WIDTH * EFBxScale; s_target_width = EFB_WIDTH * EFBxScale;
s_target_height = EFB_HEIGHT * EFByScale; s_target_height = EFB_HEIGHT * EFByScale;
s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height;
// Because of the fixed framebuffer size we need to disable the resolution // Because of the fixed framebuffer size we need to disable the resolution
// options while running // options while running
g_Config.bRunning = true; g_Config.bRunning = true;
@ -488,7 +503,7 @@ bool Renderer::Init()
return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess; return GL_REPORT_ERROR() == GL_NO_ERROR && bSuccess;
} }
void Renderer::Shutdown(void) void Renderer::Shutdown()
{ {
g_Config.bRunning = false; g_Config.bRunning = false;
UpdateActiveConfig(); UpdateActiveConfig();
@ -530,15 +545,14 @@ int Renderer::GetTargetHeight()
return s_target_height; return s_target_height;
} }
// Return the custom resolution int Renderer::GetFullTargetWidth()
int Renderer::GetCustomWidth()
{ {
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() float Renderer::GetTargetScaleX()
@ -561,17 +575,6 @@ float Renderer::GetXFBScaleY()
return yScale; return yScale;
} }
// Return the framebuffer size
int Renderer::GetFrameBufferWidth()
{
return s_target_width;
}
int Renderer::GetFrameBufferHeight()
{
return s_target_height;
}
// Create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugText() void Renderer::DrawDebugText()
{ {
@ -657,16 +660,26 @@ void Renderer::DrawDebugText()
std::string T1 = "", T2 = ""; std::string T1 = "", T2 = "";
std::vector<std::string> T0; std::vector<std::string> T0;
int W, H; std::string OSDM1;
W = OpenGL_GetBackbufferWidth(); switch(g_ActiveConfig.iEFBScale)
H = OpenGL_GetBackbufferHeight(); {
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; std::string OSDM21;
switch(g_ActiveConfig.iAspectRatio) 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) 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) 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 xoff = bpmem.scissorOffset.x * 2 - 342;
int yoff = bpmem.scissorOffset.y * 2 - 342; int yoff = bpmem.scissorOffset.y * 2 - 342;
float rc_left = (float)bpmem.scissorTL.x - xoff - 342; // left = 0 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 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 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 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_bottom > EFB_HEIGHT) rc_bottom = EFB_HEIGHT;
if(rc_left > rc_right) if (rc_left > rc_right)
{ {
int temp = rc_right; int temp = rc_right;
rc_right = rc_left; rc_right = rc_left;
rc_left = temp; rc_left = temp;
} }
if(rc_top > rc_bottom) if (rc_top > rc_bottom)
{ {
int temp = rc_bottom; int temp = rc_bottom;
rc_bottom = rc_top; rc_bottom = rc_top;
rc_top = temp; rc_top = temp;
} }
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 // Check that the coordinates are good
if (rc_right != rc_left && rc_bottom != rc_top) if (rc_right != rc_left && rc_bottom != rc_top)
{ {
glScissor( glScissor(
(int)(rc_left * EFBxScale), // x = 0 for example (int)(rc_left), // x = 0 for example
(int)((EFB_HEIGHT - rc_bottom) * EFByScale), // y = 0 for example (int)(rc_bottom), // y = 0 for example
(int)((rc_right - rc_left)* EFBxScale), // width = 640 for example (int)(rc_right), // width = 640 for example
(int)((rc_bottom - rc_top) * EFByScale) // height = 480 for example (int)(rc_top) // height = 480 for example
); );
return true; return true;
} }
@ -835,7 +867,7 @@ void Renderer::SetColorMask()
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y) u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
{ {
if(!g_ActiveConfig.bEFBAccessEnable) if (!g_ActiveConfig.bEFBAccessEnable)
return 0; return 0;
// Get the rectangular target region covered by the EFB pixel // 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.right = x + 1;
efbPixelRc.bottom = y + 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 // TODO (FIX) : currently, AA path is broken/offset and doesn't return the correct pixel
switch (type) switch (type)
@ -929,42 +961,44 @@ void UpdateViewport()
// [3] = xorig + width/2 + 342 // [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342 // [4] = yorig + height/2 + 342
// [5] = 16777215 * farz // [5] = 16777215 * farz
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 // Stretch picture with increased internal resolution
int GLx = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - scissorXOff) * int X = (int)ceil((xfregs.rawViewport[3] - xfregs.rawViewport[0] - float(scissorXOff)) * EFBxScale);
EFBxScale); int Y = (int)ceil((float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + float(scissorYOff)) * EFByScale);
int GLy = (int)ceil( int Width = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
(float(EFB_HEIGHT) - xfregs.rawViewport[4] + xfregs.rawViewport[1] + scissorYOff) * int Height = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
EFByScale);
int GLWidth = (int)ceil(2.0f * xfregs.rawViewport[0] * EFBxScale);
int GLHeight = (int)ceil(-2.0f * xfregs.rawViewport[1] * EFByScale);
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
double GLFar = xfregs.rawViewport[5] / 16777216.0f; double GLFar = xfregs.rawViewport[5] / 16777216.0f;
if(GLWidth < 0) if (Width < 0)
{ {
GLx += GLWidth; X += Width;
GLWidth*=-1; Width*=-1;
} }
if(GLHeight < 0) if (Height < 0)
{ {
GLy += GLHeight; Y += Height;
GLHeight *= -1; Height *= -1;
} }
// Update the view port // Update the view port
glViewport(GLx, GLy, GLWidth, GLHeight); glViewport(X, Y, Width, Height);
glDepthRange(GLNear, GLFar); glDepthRange(GLNear, GLFar);
} }
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
{ {
// Update the view port for clearing the picture // 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()); 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 // 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(); VertexShaderManager::SetViewportChanged();
@ -1048,10 +1082,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
DVSTARTPROFILE(); DVSTARTPROFILE();
ResetAPIState(); ResetAPIState();
TargetRectangle back_rc; TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &back_rc); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, true, &dst_rect);
// Make sure that the wireframe setting doesn't screw up the screen copy. // Make sure that the wireframe setting doesn't screw up the screen copy.
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 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); TextureCache::DisableStage(i);
// Update GLViewPort // 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(); GL_REPORT_ERRORD();
@ -1094,21 +1127,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
TargetRectangle sourceRc; TargetRectangle sourceRc;
if (g_ActiveConfig.bAutoScale || g_ActiveConfig.bUseXFB) sourceRc = xfbSource->sourceRc;
{
sourceRc = xfbSource->sourceRc;
}
else
{
sourceRc.left = 0;
sourceRc.top = xfbSource->texHeight;
sourceRc.right = xfbSource->texWidth;
sourceRc.bottom = 0;
}
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;
if (g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) if (!g_ActiveConfig.bUseRealXFB)
{ {
// use virtual xfb with offset // use virtual xfb with offset
int xfbHeight = xfbSource->srcHeight; 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.left = -(xfbWidth / (float)fbWidth);
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = (xfbWidth / (float)fbWidth);
if (!g_ActiveConfig.bAutoScale) // The following code disables auto stretch. Kept for reference.
{ // scale draw area for a 1 to 1 pixel mapping with the draw target
// scale draw area for a 1 to 1 pixel mapping with the draw target //float vScale = (float)fbHeight / (float)dst_rect.GetHeight();
float vScale = (float)fbHeight / (float)back_rc.GetHeight(); //float hScale = (float)fbWidth / (float)dst_rect.GetWidth();
float hScale = (float)fbWidth / (float)back_rc.GetWidth(); //drawRc.top *= vScale;
//drawRc.bottom *= vScale;
drawRc.top *= vScale; //drawRc.left *= hScale;
drawRc.bottom *= vScale; //drawRc.right *= hScale;
drawRc.left *= hScale;
drawRc.right *= hScale;
}
} }
else else
{ {
@ -1192,7 +1212,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
else else
{ {
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = ConvertEFBRectangle(rc);
GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(rc); GLuint read_texture = g_framebufferManager.ResolveAndGetRenderTarget(rc);
// Render to the real buffer now. // Render to the real buffer now.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the window backbuffer 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); glVertex2f( 1, -1);
glEnd(); glEnd();
} }
} }
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
TextureCache::DisableStage(0); TextureCache::DisableStage(0);
if(g_ActiveConfig.bAnaglyphStereo)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Wireframe // Wireframe
if (g_ActiveConfig.bWireFrame) if (g_ActiveConfig.bWireFrame)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 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(); s_criticalScreenshot.Enter();
// Save screenshot // Save screenshot
SaveRenderTarget(s_sScreenshotName.c_str(), back_rc); SaveRenderTarget(s_sScreenshotName.c_str(), dst_rect);
// Reset settings // Reset settings
s_sScreenshotName = ""; s_sScreenshotName = "";
s_bScreenshot = false; s_bScreenshot = false;
@ -1261,11 +1280,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (g_ActiveConfig.bDumpFrames) if (g_ActiveConfig.bDumpFrames)
{ {
s_criticalScreenshot.Enter(); s_criticalScreenshot.Enter();
int w = back_rc.GetWidth(); int w = dst_rect.GetWidth();
int h = back_rc.GetHeight(); int h = dst_rect.GetHeight();
u8 *data = (u8 *) malloc(3 * w * h); u8 *data = (u8 *) malloc(3 * w * h);
glPixelStorei(GL_PACK_ALIGNMENT, 1); 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 (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0)
{ {
if (!s_bLastFrameDumped) if (!s_bLastFrameDumped)
@ -1306,11 +1325,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
{ {
s_criticalScreenshot.Enter(); s_criticalScreenshot.Enter();
char movie_file_name[255]; char movie_file_name[255];
int w = back_rc.GetWidth(); int w = dst_rect.GetWidth();
int h = back_rc.GetHeight(); int h = dst_rect.GetHeight();
u8 *data = (u8 *) malloc(3 * w * h); u8 *data = (u8 *) malloc(3 * w * h);
glPixelStorei(GL_PACK_ALIGNMENT, 1); 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 (GL_REPORT_ERROR() == GL_NO_ERROR)
{ {
if (!s_bLastFrameDumped) if (!s_bLastFrameDumped)
@ -1348,6 +1367,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_bLastFrameDumped = false; s_bLastFrameDumped = false;
} }
#endif #endif
// Finish up the current frame, print some stats // Finish up the current frame, print some stats
OpenGL_Update(); // just updates the render window position and the backbuffer size OpenGL_Update(); // just updates the render window position and the backbuffer size
bool xfbchanged = false; bool xfbchanged = false;
@ -1364,38 +1384,47 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
bool WindowResized = false; bool WindowResized = false;
int W = (int)OpenGL_GetBackbufferWidth(), H = (int)OpenGL_GetBackbufferHeight(); int W = (int)OpenGL_GetBackbufferWidth();
if (W != s_backbuffer_width || H != s_backbuffer_height) int H = (int)OpenGL_GetBackbufferHeight();
if (W != s_backbuffer_width || H != s_backbuffer_height || s_LastEFBScale != g_ActiveConfig.iEFBScale)
{ {
WindowResized = true; WindowResized = true;
s_backbuffer_width = W; s_backbuffer_width = W;
s_backbuffer_height = H; s_backbuffer_height = H;
s_LastEFBScale = g_ActiveConfig.iEFBScale;
} }
if( xfbchanged || WindowResized) if (xfbchanged || WindowResized)
{ {
TargetRectangle dst_rect; TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
xScale = 1.0f; if(g_ActiveConfig.bUseRealXFB)
yScale = 1.0f;
if(!g_ActiveConfig.bNativeResolution)
{ {
if (g_ActiveConfig.b2xResolution) xScale = 1.0f;
{ yScale = 1.0f;
xScale = 2.0f; }
yScale = 2.0f; else
} {
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 = (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); switch(s_LastEFBScale)
EFByScale = ceilf(yScale); {
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_newFrameBufferWidth = EFB_WIDTH * EFBxScale;
int m_newFrameBufferHeight = EFB_HEIGHT * EFByScale; 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_width = m_newFrameBufferWidth;
s_target_height = m_newFrameBufferHeight; s_target_height = m_newFrameBufferHeight;
s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height;
g_framebufferManager.Shutdown(); g_framebufferManager.Shutdown();
g_framebufferManager.Init(s_target_width, s_target_height, g_framebufferManager.Init(s_target_width, s_target_height,
s_MSAASamples, s_MSAACoverageSamples); s_MSAASamples, s_MSAACoverageSamples);
@ -1617,23 +1649,6 @@ void Renderer::SetScreenshot(const char *filename)
s_criticalScreenshot.Leave(); 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) void Renderer::FlipImageData(u8 *data, int w, int h)
{ {
// Flip image upside down. Damn OpenGL. // Flip image upside down. Damn OpenGL.

View File

@ -500,7 +500,7 @@ TextureCache::TCacheEntry* TextureCache::Load(int texstage, u32 address, int wid
} }
else else
{ {
if(skip_texture_create) if (skip_texture_create)
{ {
glCompressedTexSubImage2D(target, 0,0,0,width, height, glCompressedTexSubImage2D(target, 0,0,0,width, height,
GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,expandedWidth*expandedHeight/2, temp); GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,expandedWidth*expandedHeight/2, temp);

View File

@ -309,7 +309,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
Renderer::ResetAPIState(); Renderer::ResetAPIState();
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
g_framebufferManager.SetFramebuffer(0); g_framebufferManager.SetFramebuffer(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
TextureCache::DisableStage(0); TextureCache::DisableStage(0);
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
@ -371,10 +371,9 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
cacheBytes = 64; cacheBytes = 64;
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
TextureCache::MakeRangeDynamic(address,size_in_bytes); TextureCache::MakeRangeDynamic(address,size_in_bytes);
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
} }
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight) void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
@ -400,10 +399,10 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
return; return;
} }
Renderer::ResetAPIState();
int srcFmtWidth = srcWidth / 2; int srcFmtWidth = srcWidth / 2;
Renderer::ResetAPIState(); // reset any game specific settings
// swich to texture converter frame buffer // swich to texture converter frame buffer
// attach destTexture as color destination // attach destTexture as color destination
g_framebufferManager.SetFramebuffer(s_texConvFrameBuffer); g_framebufferManager.SetFramebuffer(s_texConvFrameBuffer);

View File

@ -86,7 +86,7 @@ bool Init()
g_nativeVertexFmt = NULL; g_nativeVertexFmt = NULL;
Flushed=false; Flushed=false;
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
return true; return true;
} }
@ -181,17 +181,17 @@ void AddVertices(int primitive, int numVertices)
inline void Draw() inline void Draw()
{ {
if(IndexGenerator::GetNumTriangles() > 0) if (IndexGenerator::GetNumTriangles() > 0)
{ {
glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if(IndexGenerator::GetNumLines() > 0) if (IndexGenerator::GetNumLines() > 0)
{ {
glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if(IndexGenerator::GetNumPoints() > 0) if (IndexGenerator::GetNumPoints() > 0)
{ {
glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer);
INCSTAT(stats.thisFrame.numIndexedDrawCalls); 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 // set global constants
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(); PixelShaderManager::SetConstants();
// finally bind // finally bind
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
Draw(); Draw();
// run through vertex groups again to set alpha // 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); ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);
// only update alpha // only update alpha
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
@ -353,6 +350,5 @@ void Flush()
g_Config.iSaveTargetId++; g_Config.iSaveTargetId++;
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
} }
} // namespace } // namespace

View File

@ -50,9 +50,9 @@ Make AA apply instantly during gameplay if possible
*/ */
#include "Globals.h" #include "Globals.h"
#include "LogManager.h"
#include "Thread.h"
#include "Atomic.h" #include "Atomic.h"
#include "Thread.h"
#include "LogManager.h"
#include <cstdarg> #include <cstdarg>
@ -124,7 +124,15 @@ bool IsD3D()
return false; 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->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_VIDEO; _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
@ -143,14 +151,6 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
LogManager::SetInstance((LogManager*)globals->logManager); 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) void *DllDebugger(void *_hParent, bool Show)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
@ -205,6 +205,68 @@ void Initialize(void *init)
s_PluginInitialized = true; 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 static volatile struct
{ {
unsigned char **ptr; unsigned char **ptr;
@ -260,73 +322,6 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); 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 // Enter and exit the video loop
void Video_EnterLoop() void Video_EnterLoop()
{ {