DX11: Add an option to choose the internal resolution.
DX9: When clearing the back buffer in Renderer::Swap(), use IDirect3DDevice9::Clear instead of a clear quad if possible. Should improve performance marginally. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6373 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
a4d06f4b71
commit
38d06e76d6
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue