diff --git a/Source/Core/VideoCommon/Src/Render.h b/Source/Core/VideoCommon/Src/Render.h index b7149a02d3..90184bc4ef 100644 --- a/Source/Core/VideoCommon/Src/Render.h +++ b/Source/Core/VideoCommon/Src/Render.h @@ -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(); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index f9584fc89c..86c83b2649 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -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); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 1591f92575..e4543ea7b6 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -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 diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 98214cf6f7..1a546b2385 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -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 { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp index 3f116bf2c5..8f6a993dfa 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp @@ -59,7 +59,7 @@ void SetLineWidth(const BPCmd &bp) void SetDepthMode(const BPCmd &bp) { - Renderer::SetDepthMode(); + Renderer::SetDepthMode(); } void SetBlendMode(const BPCmd &bp) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp index 0eeceaec65..68f0766f32 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/DlgSettings.cpp @@ -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 ); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/EmuWindow.cpp b/Source/Plugins/Plugin_VideoDX9/Src/EmuWindow.cpp index c06fecf14a..7aac6ddc9e 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/EmuWindow.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/EmuWindow.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index e686fc6e91..c5667dacc7 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 2d6338a247..8161d03315 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -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 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; @@ -1104,7 +1113,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons int Y = dst_rect.top; 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 sourceRc; sourceRc.left = 0; @@ -1142,7 +1155,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons MathUtil::Rectangle 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(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 24add2eb2a..f4b4b09fc1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -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); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp index be88040012..e424edbf70 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureConverter.cpp @@ -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); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface()); 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) @@ -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) @@ -474,7 +472,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE } int srcFmtWidth = srcWidth / 2; - + Renderer::ResetAPIState(); // reset any game specific settings LPDIRECT3DTEXTURE9 s_srcTexture = D3D::CreateTexture2D(srcAddr, srcFmtWidth, srcHeight, srcFmtWidth, D3DFMT_A8R8G8B8, false); LPDIRECT3DSURFACE9 Rendersurf = NULL; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index bd5ee66e38..a6abe4b32d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h index 88770da86e..cb114b5af7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.h @@ -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. diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 506127304b..dcb2ba4e2f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp index 4a9e1ac685..8d050fc393 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.cpp @@ -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: ")); - m_2xResolution->SetToolTip(wxT( - "Applies instanty during gameplay: ")); + wxT("\n\nApplies instantly during gameplay: ")); 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)); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h index f82373398f..7fcb7f85d5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GUI/ConfigDlg.h @@ -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, diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index 7641008a70..f47f3f6d87 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -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) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp index 4e50ee4e28..1f67af795f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 611ef6b9a7..7b6b4d96ee 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -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; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h index d97d47dd7d..0354cf228f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.h @@ -57,7 +57,7 @@ class PixelShaderCache typedef std::map PSCache; - static PSCache pshaders; + static PSCache PixelShaders; static PIXELSHADERUID s_curuid; // the current pixel shader uid (progressively changed as memory is written) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index a1f6506598..ce1bf10d11 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -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 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 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. diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index 7804e8e850..2902c42403 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -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); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp index 5b9b0f27c2..4e2adeda6c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureConverter.cpp @@ -309,7 +309,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf Renderer::ResetAPIState(); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0); g_framebufferManager.SetFramebuffer(0); - VertexShaderManager::SetViewportChanged(); + VertexShaderManager::SetViewportChanged(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); TextureCache::DisableStage(0); Renderer::RestoreAPIState(); @@ -371,10 +371,9 @@ 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); + return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); } 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; } - 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); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 12d054da59..e3b9ccc0bb 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -86,7 +86,7 @@ bool Init() g_nativeVertexFmt = NULL; Flushed=false; GL_REPORT_ERRORD(); - + return true; } @@ -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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 576d10cf5c..b16b38468e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -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 @@ -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() {