D3D: Save some video RAM by turning off the "default" Z buffer (we create our own). probably doesn't matter on most video cards..

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4277 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-09-15 19:53:22 +00:00
parent e6b87febe5
commit dc4f712f74
6 changed files with 72 additions and 54 deletions

View File

@ -289,6 +289,7 @@ void CLogWindow::UpdateChecks()
void CLogWindow::UnPopulateRight() void CLogWindow::UnPopulateRight()
{ {
// Use ->Detach instead, as per sizer.h?
sRight->Remove(m_Log); sRight->Remove(m_Log);
sRight->Remove(sRightBottom); sRight->Remove(sRightBottom);
// Remove() destroys sizers // Remove() destroys sizers

View File

@ -146,13 +146,10 @@ void SetDepthMode(const BPCmd &bp)
else else
{ {
D3D::SetRenderState(D3DRS_ZENABLE, FALSE); D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
}
} }
//if (!bpmem.zmode.updateenable)
// Renderer::SetRenderMode(Renderer::RM_Normal);
}
void SetBlendMode(const BPCmd &bp) void SetBlendMode(const BPCmd &bp)
{ {
if (bp.changes & 1) if (bp.changes & 1)
@ -164,7 +161,8 @@ void SetBlendMode(const BPCmd &bp)
if (bp.changes & 0x700) if (bp.changes & 0x700)
D3D::SetRenderState(D3DRS_SRCBLEND, src); D3D::SetRenderState(D3DRS_SRCBLEND, src);
if (bp.changes & 0xE0) { if (bp.changes & 0xE0)
{
if (!bpmem.blendmode.subtract) if (!bpmem.blendmode.subtract)
{ {
D3D::SetRenderState(D3DRS_DESTBLEND, dst); D3D::SetRenderState(D3DRS_DESTBLEND, dst);

View File

@ -35,6 +35,7 @@ static bool nextFullScreen = false;
static int multisample; static int multisample;
static int resolution; static int resolution;
static int xres, yres; static int xres, yres;
static bool auto_depth_stencil = false;
#define VENDOR_NVIDIA 4318 #define VENDOR_NVIDIA 4318
#define VENDOR_ATI 4098 #define VENDOR_ATI 4098
@ -95,8 +96,14 @@ void EnableAlphaToCoverage()
ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS)); ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS));
pp->hDeviceWindow = hWnd; pp->hDeviceWindow = hWnd;
if (auto_depth_stencil)
{
pp->EnableAutoDepthStencil = TRUE; pp->EnableAutoDepthStencil = TRUE;
pp->AutoDepthStencilFormat = D3DFMT_D24S8; pp->AutoDepthStencilFormat = D3DFMT_D24S8;
} else {
pp->EnableAutoDepthStencil = FALSE;
pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN;
}
pp->BackBufferFormat = D3DFMT_A8R8G8B8; pp->BackBufferFormat = D3DFMT_A8R8G8B8;
if (aa_mode >= (int)adapters[adapter].aa_levels.size()) if (aa_mode >= (int)adapters[adapter].aa_levels.size())
aa_mode = 0; aa_mode = 0;
@ -104,7 +111,7 @@ void EnableAlphaToCoverage()
pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting; pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting;
pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting; pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting;
pp->Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; pp->Flags = auto_depth_stencil ? D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL : 0;
if (fullScreen) if (fullScreen)
{ {
xres = pp->BackBufferWidth = FSResX; xres = pp->BackBufferWidth = FSResX;
@ -214,13 +221,14 @@ void EnableAlphaToCoverage()
} }
} }
HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode) HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode, bool auto_depth)
{ {
hWnd = wnd; hWnd = wnd;
fullScreen = _fullscreen; fullScreen = _fullscreen;
nextFullScreen = _fullscreen; nextFullScreen = _fullscreen;
multisample = aa_mode; multisample = aa_mode;
resolution = _resolution; resolution = _resolution;
auto_depth_stencil = auto_depth;
cur_adapter = adapter; cur_adapter = adapter;
D3DPRESENT_PARAMETERS d3dpp; D3DPRESENT_PARAMETERS d3dpp;
InitPP(adapter, resolution, aa_mode, &d3dpp); InitPP(adapter, resolution, aa_mode, &d3dpp);
@ -254,7 +262,8 @@ void EnableAlphaToCoverage()
} }
dev->GetDeviceCaps(&caps); dev->GetDeviceCaps(&caps);
dev->GetRenderTarget(0, &back_buffer); dev->GetRenderTarget(0, &back_buffer);
dev->GetDepthStencilSurface(&back_buffer_z); if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
back_buffer_z = NULL;
// Device state would normally be set here // Device state would normally be set here
return S_OK; return S_OK;
@ -314,16 +323,20 @@ void ShowD3DError(HRESULT err)
if (dev) if (dev)
{ {
// Can't keep a pointer around to the backbuffer surface when resetting. // Can't keep a pointer around to the backbuffer surface when resetting.
if (back_buffer_z)
back_buffer_z->Release(); back_buffer_z->Release();
back_buffer_z = NULL;
back_buffer->Release(); back_buffer->Release();
back_buffer = NULL;
D3DPRESENT_PARAMETERS d3dpp; D3DPRESENT_PARAMETERS d3dpp;
InitPP(cur_adapter, resolution, multisample, &d3dpp); InitPP(cur_adapter, resolution, multisample, &d3dpp);
HRESULT hr = dev->Reset(&d3dpp); HRESULT hr = dev->Reset(&d3dpp);
ShowD3DError(hr); ShowD3DError(hr);
dev->GetRenderTarget(0, &back_buffer); dev->GetRenderTarget(0, &back_buffer);
dev->GetDepthStencilSurface(&back_buffer_z); if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND)
back_buffer_z = NULL;
} }
} }

View File

@ -29,7 +29,7 @@ namespace D3D
{ {
HRESULT Init(); HRESULT Init();
HRESULT Create(int adapter, HWND wnd, bool fullscreen, int resolution, int aa_mode); HRESULT Create(int adapter, HWND wnd, bool fullscreen, int resolution, int aa_mode, bool auto_depth);
void Close(); void Close();
void Shutdown(); void Shutdown();

View File

@ -68,11 +68,14 @@ void SetupDeviceObjects()
D3D::font.Init(); D3D::font.Init();
VertexLoaderManager::Init(); VertexLoaderManager::Init();
FBManager::Create(); FBManager::Create();
// Tex and shader caches will recreate themselves over time.
} }
// Kill off all POOL_DEFAULT device objects. // Kill off all POOL_DEFAULT device objects.
void TeardownDeviceObjects() void TeardownDeviceObjects()
{ {
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager::Destroy(); FBManager::Destroy();
D3D::font.Shutdown(); D3D::font.Shutdown();
TextureCache::Invalidate(false); TextureCache::Invalidate(false);
@ -81,8 +84,7 @@ void TeardownDeviceObjects()
VertexShaderCache::Clear(); VertexShaderCache::Clear();
PixelShaderCache::Clear(); PixelShaderCache::Clear();
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); // This really should be all but Zelda for example still fails...
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
} }
bool Renderer::Init() bool Renderer::Init()
@ -90,7 +92,8 @@ bool Renderer::Init()
UpdateActiveConfig(); UpdateActiveConfig();
int fullScreenRes, w_temp, h_temp; int fullScreenRes, w_temp, h_temp;
sscanf(g_Config.cInternalRes, "%dx%d", &w_temp, &h_temp); sscanf(g_Config.cInternalRes, "%dx%d", &w_temp, &h_temp);
if (w_temp <= 0 || h_temp <= 0) { if (w_temp <= 0 || h_temp <= 0)
{
w_temp = 640; w_temp = 640;
h_temp = 480; h_temp = 480;
} }
@ -107,7 +110,7 @@ bool Renderer::Init()
break; break;
} }
D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), g_ActiveConfig.bFullscreen, D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), g_ActiveConfig.bFullscreen,
fullScreenRes, backbuffer_ms_mode); fullScreenRes, backbuffer_ms_mode, false);
s_backbuffer_width = D3D::GetBackBufferWidth(); s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight(); s_backbuffer_height = D3D::GetBackBufferHeight();
@ -201,6 +204,35 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
} }
} }
// With D3D, we have to resize the backbuffer if the window changed
// size.
void CheckForResize()
{
while (EmuWindow::IsSizing())
{
Sleep(10);
}
RECT rcWindow;
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
int client_width = rcWindow.right - rcWindow.left;
int client_height = rcWindow.bottom - rcWindow.top;
// Sanity check.
if ((client_width != s_backbuffer_width ||
client_height != s_backbuffer_height) &&
client_width >= 4 && client_height >= 4)
{
TeardownDeviceObjects();
D3D::Reset();
SetupDeviceObjects();
s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight();
}
}
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{ {
if (g_bSkipCurrentFrame) if (g_bSkipCurrentFrame)
@ -310,49 +342,23 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
UpdateActiveConfig(); UpdateActiveConfig();
// TODO: Resize backbuffer if window size has changed. This code crashes, debug it. // TODO: Resize backbuffer if window size has changed. This code crashes, debug it.
while (EmuWindow::IsSizing())
{
Sleep(10);
}
RECT rcWindow;
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
int client_width = rcWindow.right - rcWindow.left;
int client_height = rcWindow.bottom - rcWindow.top;
if ((client_width != s_backbuffer_width ||
client_height != s_backbuffer_height) &&
client_width >= 4 && client_height >= 4)
{
TeardownDeviceObjects();
D3D::Reset();
SetupDeviceObjects();
s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight();
}
g_VideoInitialize.pCopiedToXFB(false); g_VideoInitialize.pCopiedToXFB(false);
CheckForResize();
// Begin new frame // Begin new frame
// Set default viewport and scissor, for the clear to work correctly // Set default viewport and scissor, for the clear to work correctly
stats.ResetFrame(); stats.ResetFrame();
// u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; // u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
D3D::BeginFrame(); D3D::BeginFrame();
// Clear backbuffer. We probably don't need to do this every frame.
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0); D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0);
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
D3D::dev->SetRenderState(D3DRS_ZENABLE, TRUE);
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = (DWORD)s_target_width;
vp.Height = (DWORD)s_target_height;
vp.MinZ = 0;
vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp);
RECT rc; RECT rc;
rc.left = 0; rc.left = 0;

View File

@ -284,7 +284,7 @@ void Shutdown()
void DoState(unsigned char **ptr, int mode) { void DoState(unsigned char **ptr, int mode) {
// Clear texture cache because it might have written to RAM // Clear texture cache because it might have written to RAM
TextureCache::Invalidate(false); TextureCache::Invalidate(false);
// No need to clear shader caches.
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
VideoCommon_DoState(p); VideoCommon_DoState(p);
} }