diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 9c34db2bd8..561891e29b 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -247,6 +247,8 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) IndexBuffer = NULL; FBTexture = NULL; TempRenderTexture = NULL; + RenderTexture[0] = NULL; + RenderTexture[1] = NULL; InitialWipeScreen = NULL; ScreenshotTexture = NULL; ScreenshotSurface = NULL; @@ -277,6 +279,8 @@ D3DFB::D3DFB (int width, int height, bool fullscreen) Packs = NULL; PixelDoubling = 0; SkipAt = -1; + CurrRenderTexture = 0; + RenderTextureToggle = 0; Gamma = 1.0; FlashColor0 = 0; @@ -624,15 +628,9 @@ void D3DFB::ReleaseResources () void D3DFB::ReleaseDefaultPoolItems() { SAFE_RELEASE( FBTexture ); - if (FinalWipeScreen != NULL) - { - if (FinalWipeScreen != TempRenderTexture) - { - FinalWipeScreen->Release(); - } - FinalWipeScreen = NULL; - } - SAFE_RELEASE( TempRenderTexture ); + SAFE_RELEASE( FinalWipeScreen ); + SAFE_RELEASE( RenderTexture[0] ); + SAFE_RELEASE( RenderTexture[1] ); SAFE_RELEASE( InitialWipeScreen ); SAFE_RELEASE( VertexBuffer ); SAFE_RELEASE( IndexBuffer ); @@ -772,24 +770,42 @@ bool D3DFB::CreateFBTexture () FBWidth = Width; FBHeight = Height; } - if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &TempRenderTexture, NULL))) + RenderTextureToggle = 0; + RenderTexture[0] = NULL; + RenderTexture[1] = NULL; + if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[0], NULL))) { - TempRenderTexture = NULL; + return false; + } + if (Windowed || PixelDoubling) + { + // Windowed or pixel doubling: Create another render texture so we can flip between them. + RenderTextureToggle = 1; + if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[1], NULL))) + { + return false; + } } else { - // Initialize the TempRenderTexture to black. + // Fullscreen and not pixel doubling: Create a render target to have the back buffer copied to. + if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL))) + { + return false; + } + } + // Initialize the TempRenderTextures to black. + for (int i = 0; i <= RenderTextureToggle; ++i) + { IDirect3DSurface9 *surf; - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &surf))) + if (SUCCEEDED(RenderTexture[i]->GetSurfaceLevel(0, &surf))) { D3DDevice->ColorFill(surf, NULL, D3DCOLOR_XRGB(0,0,0)); surf->Release(); } } - if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL))) - { - return false; - } + TempRenderTexture = RenderTexture[0]; + CurrRenderTexture = 0; return true; } @@ -1179,6 +1195,13 @@ void D3DFB::Flip() } D3DDevice->Present(NULL, NULL, NULL, NULL); InScene = false; + + if (RenderTextureToggle) + { + // Flip the TempRenderTexture to the other one now. + CurrRenderTexture ^= RenderTextureToggle; + TempRenderTexture = RenderTexture[CurrRenderTexture]; + } } //========================================================================== @@ -1198,10 +1221,10 @@ void D3DFB::CopyNextFrontBuffer() if (Windowed || PixelDoubling) { // Windowed mode or pixel doubling: TempRenderTexture has what we want + SAFE_RELEASE( FrontCopySurface ); if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &backbuff))) { - D3DDevice->StretchRect(backbuff, NULL, FrontCopySurface, NULL, D3DTEXF_NONE); - backbuff->Release(); + FrontCopySurface = backbuff; } } else diff --git a/src/win32/fb_d3d9_wipe.cpp b/src/win32/fb_d3d9_wipe.cpp index 798a950800..9a3b34412d 100644 --- a/src/win32/fb_d3d9_wipe.cpp +++ b/src/win32/fb_d3d9_wipe.cpp @@ -173,14 +173,14 @@ bool D3DFB::WipeStartScreen(int type) 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &FinalWipeScreen, NULL))) { - FinalWipeScreen = TempRenderTexture; + (FinalWipeScreen = TempRenderTexture)->AddRef(); } tsurf->Release(); } } else { - FinalWipeScreen = TempRenderTexture; + (FinalWipeScreen = TempRenderTexture)->AddRef(); } // Make even fullscreen model render to the TempRenderTexture, so @@ -229,7 +229,11 @@ void D3DFB::WipeEndScreen() // If these are different, reverse their roles so we don't need to // waste time copying from TempRenderTexture to FinalWipeScreen. - swap(FinalWipeScreen, TempRenderTexture); + if (FinalWipeScreen != TempRenderTexture) + { + swap(RenderTexture[CurrRenderTexture], FinalWipeScreen); + TempRenderTexture = RenderTexture[CurrRenderTexture]; + } // At this point, InitialWipeScreen holds the screen we are wiping from. // FinalWipeScreen holds the screen we are wiping to, which may be the @@ -315,11 +319,7 @@ void D3DFB::WipeCleanup() ScreenWipe = NULL; } SAFE_RELEASE( InitialWipeScreen ); - if (FinalWipeScreen != NULL && FinalWipeScreen != TempRenderTexture) - { - FinalWipeScreen->Release(); - } - FinalWipeScreen = NULL; + SAFE_RELEASE( FinalWipeScreen ); GatheringWipeScreen = false; if (!Accel2D) { diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index e311049b7b..9bdfd10727 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -395,6 +395,8 @@ private: int PixelDoubling; int SkipAt; int LBOffsetI; + int RenderTextureToggle; + int CurrRenderTexture; float LBOffset; float Gamma; bool UpdatePending; @@ -415,7 +417,7 @@ private: IDirect3DDevice9 *D3DDevice; IDirect3DTexture9 *FBTexture; - IDirect3DTexture9 *TempRenderTexture; + IDirect3DTexture9 *TempRenderTexture, *RenderTexture[2]; IDirect3DTexture9 *PaletteTexture; IDirect3DTexture9 *GammaTexture; IDirect3DTexture9 *ScreenshotTexture;