From dc4f712f74f853e4f3a66f711b8b5d3f4265d9bb Mon Sep 17 00:00:00 2001 From: hrydgard Date: Tue, 15 Sep 2009 19:53:22 +0000 Subject: [PATCH] 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 --- Source/Core/DolphinWX/Src/LogWindow.cpp | 1 + .../Plugin_VideoDX9/Src/BPFunctions.cpp | 10 +-- .../Plugins/Plugin_VideoDX9/Src/D3DBase.cpp | 31 ++++--- Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 80 ++++++++++--------- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 2 +- 6 files changed, 72 insertions(+), 54 deletions(-) diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp index 7814a4c7e3..042abcb116 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogWindow.cpp @@ -289,6 +289,7 @@ void CLogWindow::UpdateChecks() void CLogWindow::UnPopulateRight() { + // Use ->Detach instead, as per sizer.h? sRight->Remove(m_Log); sRight->Remove(sRightBottom); // Remove() destroys sizers diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp index 27604dc163..5843e681b6 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp @@ -146,13 +146,10 @@ void SetDepthMode(const BPCmd &bp) else { 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) { if (bp.changes & 1) @@ -164,7 +161,8 @@ void SetBlendMode(const BPCmd &bp) if (bp.changes & 0x700) D3D::SetRenderState(D3DRS_SRCBLEND, src); - if (bp.changes & 0xE0) { + if (bp.changes & 0xE0) + { if (!bpmem.blendmode.subtract) { D3D::SetRenderState(D3DRS_DESTBLEND, dst); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp index 1ece923ce7..6792b3418b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp @@ -35,6 +35,7 @@ static bool nextFullScreen = false; static int multisample; static int resolution; static int xres, yres; +static bool auto_depth_stencil = false; #define VENDOR_NVIDIA 4318 #define VENDOR_ATI 4098 @@ -95,8 +96,14 @@ void EnableAlphaToCoverage() ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS)); pp->hDeviceWindow = hWnd; - pp->EnableAutoDepthStencil = TRUE; - pp->AutoDepthStencilFormat = D3DFMT_D24S8; + if (auto_depth_stencil) + { + pp->EnableAutoDepthStencil = TRUE; + pp->AutoDepthStencilFormat = D3DFMT_D24S8; + } else { + pp->EnableAutoDepthStencil = FALSE; + pp->AutoDepthStencilFormat = D3DFMT_UNKNOWN; + } pp->BackBufferFormat = D3DFMT_A8R8G8B8; if (aa_mode >= (int)adapters[adapter].aa_levels.size()) aa_mode = 0; @@ -104,7 +111,7 @@ void EnableAlphaToCoverage() pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_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) { 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; fullScreen = _fullscreen; nextFullScreen = _fullscreen; multisample = aa_mode; resolution = _resolution; + auto_depth_stencil = auto_depth; cur_adapter = adapter; D3DPRESENT_PARAMETERS d3dpp; InitPP(adapter, resolution, aa_mode, &d3dpp); @@ -254,7 +262,8 @@ void EnableAlphaToCoverage() } dev->GetDeviceCaps(&caps); 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 return S_OK; @@ -314,16 +323,20 @@ void ShowD3DError(HRESULT err) if (dev) { // Can't keep a pointer around to the backbuffer surface when resetting. - back_buffer_z->Release(); + if (back_buffer_z) + back_buffer_z->Release(); + back_buffer_z = NULL; back_buffer->Release(); + back_buffer = NULL; + D3DPRESENT_PARAMETERS d3dpp; InitPP(cur_adapter, resolution, multisample, &d3dpp); - HRESULT hr = dev->Reset(&d3dpp); - ShowD3DError(hr); + dev->GetRenderTarget(0, &back_buffer); - dev->GetDepthStencilSurface(&back_buffer_z); + if (dev->GetDepthStencilSurface(&back_buffer_z) == D3DERR_NOTFOUND) + back_buffer_z = NULL; } } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h index fdfa1d5d72..1d8cecadc9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h @@ -29,7 +29,7 @@ namespace D3D { 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 Shutdown(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index da65ae36a3..db439319ea 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -68,11 +68,14 @@ void SetupDeviceObjects() D3D::font.Init(); VertexLoaderManager::Init(); FBManager::Create(); + // Tex and shader caches will recreate themselves over time. } // Kill off all POOL_DEFAULT device objects. void TeardownDeviceObjects() { + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); FBManager::Destroy(); D3D::font.Shutdown(); TextureCache::Invalidate(false); @@ -80,9 +83,8 @@ void TeardownDeviceObjects() VertexLoaderManager::Shutdown(); VertexShaderCache::Clear(); PixelShaderCache::Clear(); - - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); + + // This really should be all but Zelda for example still fails... } bool Renderer::Init() @@ -90,7 +92,8 @@ bool Renderer::Init() UpdateActiveConfig(); int fullScreenRes, 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; h_temp = 480; } @@ -107,7 +110,7 @@ bool Renderer::Init() break; } 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_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) { if (g_bSkipCurrentFrame) @@ -310,49 +342,23 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect UpdateActiveConfig(); // 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); + CheckForResize(); + + // Begin new frame // Set default viewport and scissor, for the clear to work correctly stats.ResetFrame(); // u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB; 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->SetRenderTarget(0, FBManager::GetEFBColorRTSurface()); D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface()); - - 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); + D3D::dev->SetRenderState(D3DRS_ZENABLE, TRUE); RECT rc; rc.left = 0; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index bb7ede8192..e344a7bec8 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -284,7 +284,7 @@ void Shutdown() void DoState(unsigned char **ptr, int mode) { // Clear texture cache because it might have written to RAM TextureCache::Invalidate(false); - + // No need to clear shader caches. PointerWrap p(ptr, mode); VideoCommon_DoState(p); }