diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 6aa01dfa68..e071bad2ba 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -54,7 +54,6 @@ enum // If this is enabled, bounding boxes will be computed for everything drawn. // This can theoretically have a big speed hit in some geom heavy games. Needs more work. // Helps some effects in Paper Mario (but they aren't quite right yet). -// May help Super Mario Galaxy? // Do testing to figure out if the speed hit is bad? // #define BBOX_SUPPORT diff --git a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp index fa136dcb83..23dc5e6edc 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/DlgSettings.cpp @@ -88,6 +88,21 @@ struct TabDirect3D : public W32Util::Tab } ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ASPECTRATIO), g_Config.iAspectRatio); + for (unsigned int i = 0; i < 5; i++) + { + const char* options[] = { + "Auto (quality)", + "Auto (compatibility)", + "Native (640x528)", + "2x (1280x1056)", + "3x (1920x1584)" + }; + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, options[i], -1, tempwstr, 2000); + ComboBox_AddString(GetDlgItem(hDlg, IDC_INTERNALRESOLUTION), tempwstr); + } + ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_INTERNALRESOLUTION), g_Config.iEFBScale); + + Button_SetCheck(GetDlgItem(hDlg, IDC_WIDESCREEN_HACK), g_Config.bWidescreenHack); Button_SetCheck(GetDlgItem(hDlg, IDC_VSYNC), g_Config.bVSync); Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE), g_Config.bSafeTextureCache); @@ -95,7 +110,6 @@ struct TabDirect3D : public W32Util::Tab Button_SetCheck(GetDlgItem(hDlg, IDC_ENABLEPIXELLIGHTING), g_Config.bEnablePixelLigting); - if (g_Config.iSafeTextureCache_ColorSamples == 0) { Button_SetCheck(GetDlgItem(hDlg, IDC_SAFE_TEXTURE_CACHE_SAFE), true); @@ -128,6 +142,9 @@ struct TabDirect3D : public W32Util::Tab case IDC_ADAPTER: g_Config.iAdapter = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ADAPTER)); break; + case IDC_INTERNALRESOLUTION: + g_Config.iEFBScale = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_INTERNALRESOLUTION)); + break; case IDC_VSYNC: g_Config.bVSync = Button_GetCheck(GetDlgItem(hDlg, IDC_VSYNC)) ? true : false; break; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp index f0eda8faf9..4f38b8c483 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp @@ -182,11 +182,12 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) { // Replace the last virtual XFB (might cause glitches, but better than allocating 50 XFBs...) + // TODO: Reencode last virtual XFB to RAM to avoid glitches? --it; } - float scaleX = Renderer::GetTargetScaleX(); - float scaleY = Renderer::GetTargetScaleY(); + float scaleX = Renderer::GetXFBScaleX(); + float scaleY = Renderer::GetXFBScaleY(); TargetRectangle targetSource,efbSource; efbSource = Renderer::ConvertEFBRectangle(sourceRc); targetSource.top = (int)(sourceRc.top * scaleY); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 928c976ff0..aed30f1c96 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -65,10 +65,16 @@ static int s_backbuffer_height; static int s_XFB_width; static int s_XFB_height; +// ratio of backbuffer size and render area size static float xScale; static float yScale; +// Internal resolution scale (related to xScale/yScale for "Auto" scaling) +static float EFBxScale; +static float EFByScale; + static u32 s_blendMode; +static u32 s_LastEFBScale; static bool XFBWrited; static bool s_bScreenshot = false; @@ -349,8 +355,24 @@ bool Renderer::Init() xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width; yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height; - s_target_width = (int)(EFB_WIDTH * xScale); - s_target_height = (int)(EFB_HEIGHT * 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 = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); + break; + }; + + s_target_width = (int)(EFB_WIDTH * EFBxScale); + s_target_height = (int)(EFB_HEIGHT * EFByScale); s_Fulltarget_width = s_target_width; s_Fulltarget_height = s_target_height; @@ -388,8 +410,10 @@ int Renderer::GetTargetWidth() { return s_target_width; } int Renderer::GetTargetHeight() { return s_target_height; } int Renderer::GetFullTargetWidth() { return s_Fulltarget_width; } int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; } -float Renderer::GetTargetScaleX() { return xScale; } -float Renderer::GetTargetScaleY() { return yScale; } +float Renderer::GetTargetScaleX() { return EFBxScale; } +float Renderer::GetTargetScaleY() { return EFByScale; } +float Renderer::GetXFBScaleX() { return xScale; } +float Renderer::GetXFBScaleY() { return yScale; } // Return the framebuffer size int Renderer::GetFrameBufferWidth() @@ -486,10 +510,10 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) 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 * xScale) + Xstride; - result.top = (int)(rc.top * yScale) + Ystride; - result.right = (int)(rc.right * xScale) + Xstride; - result.bottom = (int)(rc.bottom * yScale) + Ystride; + result.left = (int)(rc.left * EFBxScale) + Xstride; + result.top = (int)(rc.top * EFByScale) + Ystride; + result.right = (int)(rc.right * EFBxScale) + Xstride; + result.bottom = (int)(rc.bottom * EFByScale) + Ystride; return result; } @@ -557,10 +581,10 @@ bool Renderer::SetScissorRect() int Xstride = (s_Fulltarget_width - s_target_width) / 2; int Ystride = (s_Fulltarget_height - s_target_height) / 2; - rc.left = (int)(rc.left * xScale); - rc.top = (int)(rc.top * yScale); - rc.right = (int)(rc.right * xScale); - rc.bottom = (int)(rc.bottom * yScale); + rc.left = (int)(rc.left * EFBxScale); + rc.top = (int)(rc.top * EFByScale); + rc.right = (int)(rc.right * EFBxScale); + rc.bottom = (int)(rc.bottom * EFByScale); if (rc.left < 0) rc.left = 0; if (rc.right < 0) rc.right = 0; @@ -758,17 +782,14 @@ 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; // 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((int)(2 * xfregs.rawViewport[0]) * EFBxScale); + int Height = (int)ceil((int)(-2 * xfregs.rawViewport[1]) * EFByScale); if (Width < 0) { X += Width; @@ -1085,8 +1106,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons // Flip/present backbuffer to frontbuffer here D3D::Present(); - // resize the back buffers NOW to avoid flickering when resizing windows - if (xfbchanged || WindowResized) + // resize the back buffers NOW to avoid flickering + if (xfbchanged || WindowResized || + s_LastEFBScale != g_ActiveConfig.iEFBScale) { // TODO: Aren't we still holding a reference to the back buffer right now? D3D::Reset(); @@ -1098,8 +1120,24 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons xScale = (float)(dst_rect.right - dst_rect.left) / (float)s_XFB_width; yScale = (float)(dst_rect.bottom - dst_rect.top) / (float)s_XFB_height; - s_target_width = (int)(EFB_WIDTH * xScale); - s_target_height = (int)(EFB_HEIGHT * 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 = EFByScale = (float)(g_ActiveConfig.iEFBScale - 1); + break; + }; + + s_target_width = (int)(EFB_WIDTH * EFBxScale); + s_target_height = (int)(EFB_HEIGHT * EFByScale); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); g_framebufferManager.Destroy(); @@ -1112,10 +1150,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV()); UpdateViewport(); VertexShaderManager::SetViewportChanged(); - // For testing zbuffer targets. - // Renderer::SetZBufferRender(); - // SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget, - // GetTargetWidth(), GetTargetHeight()); + g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB); XFBWrited = false; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.h b/Source/Plugins/Plugin_VideoDX11/Src/resource.h index fda3150de9..c823ff293e 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.h @@ -32,6 +32,7 @@ #define IDC_ENABLEPIXELLIGHTING 1045 #define IDC_LOADHIRESTEXTURE 1046 #define IDC_DUMPTEXTURES 1047 +#define IDC_INTERNALRESOLUTION 1048 #define IDC_STATIC -1 // Next default values for new objects diff --git a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc index c36405f745..12a869f8e0 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/resource.rc +++ b/Source/Plugins/Plugin_VideoDX11/Src/resource.rc @@ -40,19 +40,20 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_BORDER | WS_SYSMENU FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN LTEXT "A&dapter:",IDC_STATIC,9,10,48,8 - COMBOBOX IDC_ADAPTER,60,8,169,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "&V-Sync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,61,25,36,8 + COMBOBOX IDC_ADAPTER,80,8,149,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "&V-Sync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,25,36,8 CONTROL "&Widescreen Hack",IDC_WIDESCREEN_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,161,25,67,10 LTEXT "&Aspect Ratio:",IDC_STATIC,9,40,48,8 - COMBOBOX IDC_ASPECTRATIO,60,38,89,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "&Enable CPU->EFB access ",IDC_EFB_ACCESS_ENABLE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,60,94,11 - CONTROL "Enable &Safe Texture Cache",IDC_SAFE_TEXTURE_CACHE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,74,108,11 - CONTROL "Safe",IDC_SAFE_TEXTURE_CACHE_SAFE,"Button",BS_AUTORADIOBUTTON,20,87,32,10 - CONTROL "Normal",IDC_SAFE_TEXTURE_CACHE_NORMAL,"Button",BS_AUTORADIOBUTTON,52,87,40,10 - CONTROL "Fast",IDC_SAFE_TEXTURE_CACHE_FAST,"Button",BS_AUTORADIOBUTTON,92,87,32,10 - CONTROL "Enable Dlist Caching",IDC_DLIST_CACHING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,98,80,10 - CONTROL "Enable Pixel Lighting",IDC_ENABLEPIXELLIGHTING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,112,81,10 + COMBOBOX IDC_ASPECTRATIO,80,38,89,57,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Internal resolution:",IDC_STATIC,9,58,80,8 + COMBOBOX IDC_INTERNALRESOLUTION,80,56,89,57,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "&Enable CPU->EFB access ",IDC_EFB_ACCESS_ENABLE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,7,75,94,11 + CONTROL "Enable &Safe Texture Cache",IDC_SAFE_TEXTURE_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,89,108,11 + CONTROL "Safe",IDC_SAFE_TEXTURE_CACHE_SAFE,"Button",BS_AUTORADIOBUTTON,20,102,32,10 + CONTROL "Normal",IDC_SAFE_TEXTURE_CACHE_NORMAL,"Button",BS_AUTORADIOBUTTON,52,102,40,10 + CONTROL "Fast",IDC_SAFE_TEXTURE_CACHE_FAST,"Button",BS_AUTORADIOBUTTON,92,102,32,10 + CONTROL "Enable Dlist Caching",IDC_DLIST_CACHING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,113,80,10 + CONTROL "Enable Pixel Lighting",IDC_ENABLEPIXELLIGHTING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,127,81,10 END IDD_ADVANCED DIALOGEX 0, 0, 244, 200 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index b95ff6ff09..1fe95dfa88 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -67,9 +67,11 @@ static int s_backbuffer_height; static int s_XFB_width; static int s_XFB_height; +// ratio of backbuffer size and render area size static float xScale; static float yScale; +// Internal resolution scale (related to xScale/yScale for "Auto" scaling) static float EFBxScale; static float EFByScale; @@ -1036,7 +1038,6 @@ void Renderer::SetBlendMode(bool forceUpdate) } } -static bool RightFrame = false; // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc) { @@ -1061,6 +1062,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons ResetAPIState(); if(g_ActiveConfig.bAnaglyphStereo) { + static bool RightFrame = false; if(RightFrame) { D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); @@ -1088,15 +1090,21 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3DVIEWPORT9 vp; // Clear full target screen (edges, borders etc) - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - //D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + if(g_ActiveConfig.bAnaglyphStereo) { + // use a clear quad to keep old red or blue/green data + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); + D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + } + else + { + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + } int X = dst_rect.left; int Y = dst_rect.top; @@ -1349,7 +1357,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons EFByScale = EFBxScale; break; }; - + EFBxScale *= SupersampleCoeficient; EFByScale *= SupersampleCoeficient;