diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp index a89cbc1d8..8e385247d 100644 --- a/src/CxbxKrnl/EmuD3D8.cpp +++ b/src/CxbxKrnl/EmuD3D8.cpp @@ -156,6 +156,7 @@ static UINT QuadToTriangleD3DIndexBuffer_Size = 0; // = static XTL::INDEX16 *pQuadToTriangleIndexBuffer = nullptr; static UINT QuadToTriangleIndexBuffer_Size = 0; // = NrOfQuadVertices +static XTL::X_D3DSurface *g_XboxBackBufferSurface = NULL; static XTL::X_D3DSurface *g_pXboxRenderTarget = NULL; static XTL::X_D3DSurface *g_pXboxDepthStencil = NULL; static BOOL g_fYuvEnabled = FALSE; @@ -4601,8 +4602,23 @@ DWORD WINAPI XTL::EMUPATCH(D3DDevice_Swap) EmuWarning("XTL::EmuD3DDevice_Swap: Flags != 0"); CxbxReleaseBackBufferLock(); - g_pD3DDevice->EndScene(); + + // Blit the Xbox BackBuffer to the Host + if (g_XboxBackBufferSurface != NULL) { + auto pXboxBackBufferHostSurface = GetHostSurface(g_XboxBackBufferSurface); + + // Now we can fetch the host backbuffer + XTL::IDirect3DSurface *pCurrentHostBackBuffer = nullptr; + g_pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pCurrentHostBackBuffer); + if (pCurrentHostBackBuffer && pXboxBackBufferHostSurface) { + HRESULT hRet = D3DXLoadSurfaceFromSurface(pCurrentHostBackBuffer, nullptr, nullptr, pXboxBackBufferHostSurface, nullptr, nullptr, D3DX_DEFAULT, 0); + if (hRet != D3D_OK) { + EmuWarning("FAILED: %X", hRet); + } + } + } + HRESULT hRet = g_pD3DDevice->Present(0, 0, 0, 0); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->Present"); hRet = g_pD3DDevice->BeginScene(); @@ -4958,7 +4974,6 @@ void CreateHostResource(XTL::X_D3DResource *pResource, int iTextureStage, DWORD // Create the surface/volume/(volume/cube/)texture switch (XboxResourceType) { case XTL::X_D3DRTYPE_SURFACE: { -#if 0 // TODO : Get this to work (test case Dolphin turns black with this enabled) if (D3DUsage & D3DUSAGE_RENDERTARGET) { hRet = g_pD3DDevice->CreateRenderTarget(dwWidth, dwHeight, PCFormat, g_EmuCDPD.HostPresentationParameters.MultiSampleType, @@ -4973,7 +4988,6 @@ void CreateHostResource(XTL::X_D3DResource *pResource, int iTextureStage, DWORD ); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateRenderTarget"); } else -#endif if (D3DUsage & D3DUSAGE_DEPTHSTENCIL) { hRet = g_pD3DDevice->CreateDepthStencilSurface(dwWidth, dwHeight, PCFormat, g_EmuCDPD.HostPresentationParameters.MultiSampleType, @@ -7935,6 +7949,17 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderTarget) IDirect3DSurface *pHostRenderTarget = nullptr; IDirect3DSurface *pHostDepthStencil = nullptr; + // In Xbox titles, CreateDevice calls SetRenderTarget for the back buffer + // We can use this to determine the Xbox backbuffer surface for later use! + if (g_XboxBackBufferSurface == NULL) { + g_XboxBackBufferSurface = pRenderTarget; + } + + // If we got a null, set the Xbox Render Target to the Xbox Backbuffer + if (pRenderTarget == NULL) { + pRenderTarget = g_XboxBackBufferSurface; + } + // The current render target is only replaced if it's passed in here non-null if (pRenderTarget != NULL) { g_pXboxRenderTarget = pRenderTarget; @@ -7954,15 +7979,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderTarget) #else hRet = g_pD3DDevice->SetRenderTarget(pHostRenderTarget, pHostDepthStencil); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderTarget"); -#if 0 // tmp test - if ((hRet != D3D_OK) && pHostDepthStencil) { - // HACK : retry a failed SetRenderTarget without a depth-stencil - // (obviously, this will cause render issues, but the lack - // of render-target itself is even less desirable, so ...) - hRet = g_pD3DDevice->SetRenderTarget(pHostRenderTarget, nullptr); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderTarget"); - } -#endif #endif } diff --git a/src/CxbxKrnl/EmuD3D8/Convert.cpp b/src/CxbxKrnl/EmuD3D8/Convert.cpp index 81e3190c3..ee4d79a52 100755 --- a/src/CxbxKrnl/EmuD3D8/Convert.cpp +++ b/src/CxbxKrnl/EmuD3D8/Convert.cpp @@ -944,12 +944,12 @@ static const FormatInfo FormatInfos[] = { /* 0x3F X_D3DFMT_LIN_A8B8G8R8 */ { 32, Linear, A8B8G8R8, XTL::D3DFMT_A8B8G8R8 }, // Note : D3DFMT_A8B8G8R8=32 D3DFMT_Q8W8V8U8=63 // TODO : Needs testcase. #else // Direct3D8 : /* 0x2B X_D3DFMT_F24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int) - /* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not. - /* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) + /* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not. + /* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16, DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) /* 0x2E X_D3DFMT_LIN_D24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer }, /* 0x2F X_D3DFMT_LIN_F24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_LIN_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int) - /* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not. - /* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) + /* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not. + /* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16, DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int) /* 0x32 X_D3DFMT_L16 */ { 16, Swzzld, _____L16, XTL::D3DFMT_A8L8 , Texture, "X_D3DFMT_L16 -> D3DFMT_A8L8" }, /* 0x33 X_D3DFMT_V16U16 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_V16U16 }, /* 0x34 undefined */ {}, @@ -1147,9 +1147,12 @@ XTL::X_D3DFORMAT XTL::EmuPC2XB_D3DFormat(D3DFORMAT Format) break; // Linear // Result := X_D3DFMT_L8; // Swizzled - case D3DFMT_D16: case D3DFMT_D16_LOCKABLE: + case D3DFMT_D16: // Swizzled + return X_D3DFMT_D16; + break; + case D3DFMT_D16_LOCKABLE: // Swizzled result = X_D3DFMT_D16_LOCKABLE; - break; // Swizzled + break; case D3DFMT_UNKNOWN: result = ((X_D3DFORMAT)0xffffffff);