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:
NeoBrainX 2010-11-10 16:43:27 +00:00
parent a4d06f4b71
commit 38d06e76d6
7 changed files with 115 additions and 53 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;