Merge pull request #1648 from LukeUsher/fix-viewport-resolution-change
Fix black screen in some titles when switching resolutions during gameplay
This commit is contained in:
commit
4574b4bbdb
|
@ -3207,15 +3207,40 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetViewport)
|
||||||
DWORD top = std::max((int)pViewport->Y, 0);
|
DWORD top = std::max((int)pViewport->Y, 0);
|
||||||
DWORD right = std::min((int)pViewport->X + (int)pViewport->Width, (int)XboxRenderTarget_Width);
|
DWORD right = std::min((int)pViewport->X + (int)pViewport->Width, (int)XboxRenderTarget_Width);
|
||||||
DWORD bottom = std::min((int)pViewport->Y + (int)pViewport->Height, (int)XboxRenderTarget_Height);
|
DWORD bottom = std::min((int)pViewport->Y + (int)pViewport->Height, (int)XboxRenderTarget_Height);
|
||||||
|
DWORD width = right - left;
|
||||||
|
DWORD height = bottom - top;
|
||||||
|
|
||||||
XboxViewPort.X = left;
|
XboxViewPort.X = left;
|
||||||
XboxViewPort.Y = top;
|
XboxViewPort.Y = top;
|
||||||
XboxViewPort.Width = right - left;
|
XboxViewPort.Width = width;
|
||||||
XboxViewPort.Height = bottom - top;
|
XboxViewPort.Height = height;
|
||||||
XboxViewPort.MinZ = pViewport->MinZ;
|
XboxViewPort.MinZ = pViewport->MinZ;
|
||||||
XboxViewPort.MaxZ = pViewport->MaxZ;
|
XboxViewPort.MaxZ = pViewport->MaxZ;
|
||||||
|
|
||||||
if (g_ScaleViewport) {
|
// This operation is often used to change the display resolution without calling SetRenderTarget!
|
||||||
|
// This works by updating the underlying Width & Height of the Xbox surface, without reallocating the data
|
||||||
|
// Because of this, we need to validate that the associated host resource still matches the dimensions of the Xbox Render Target
|
||||||
|
// If not, we must force them to be re-created
|
||||||
|
// TEST CASE: Chihiro Factory Test Program
|
||||||
|
DWORD HostRenderTarget_Width = 0, HostRenderTarget_Height = 0;
|
||||||
|
GetHostRenderTargetDimensions(&HostRenderTarget_Width, &HostRenderTarget_Height);
|
||||||
|
if (HostRenderTarget_Width != XboxRenderTarget_Width || HostRenderTarget_Height != XboxRenderTarget_Height) {
|
||||||
|
LOG_TEST_CASE("RenderTarget width/height changed without calling SetRenderTarget");
|
||||||
|
|
||||||
|
// NOTE: If the host backbuffer hack is enabled, we must skip this operation for the back buffer, otherwise everything will break
|
||||||
|
// In that situation, there's nothing we can do without causing damage.
|
||||||
|
if (!g_DirectHostBackBufferAccess && g_pXboxRenderTarget != g_XboxBackBufferSurface) {
|
||||||
|
FreeHostResource(GetHostResourceKey(g_pXboxRenderTarget)); g_pD3DDevice->SetRenderTarget(0, GetHostSurface(g_pXboxRenderTarget, D3DUSAGE_RENDERTARGET));
|
||||||
|
FreeHostResource(GetHostResourceKey(g_pXboxDepthStencil)); g_pD3DDevice->SetDepthStencilSurface(GetHostSurface(g_pXboxRenderTarget, D3DUSAGE_DEPTHSTENCIL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the updated viewport data ready to pass to host SetViewPort
|
||||||
|
HostViewPort = XboxViewPort;
|
||||||
|
|
||||||
|
// We *must* scale the viewport when using the DirectHostBackBuffer hack for the backbuffer render target
|
||||||
|
// Otherwise, we only get partial screen updates
|
||||||
|
if (g_ScaleViewport || (g_DirectHostBackBufferAccess && g_pXboxRenderTarget == g_XboxBackBufferSurface)) {
|
||||||
// Get current host render target dimensions
|
// Get current host render target dimensions
|
||||||
DWORD HostRenderTarget_Width;
|
DWORD HostRenderTarget_Width;
|
||||||
DWORD HostRenderTarget_Height;
|
DWORD HostRenderTarget_Height;
|
||||||
|
@ -3229,8 +3254,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetViewport)
|
||||||
// TODO : Fix test-case Shenmue 2 (which halves height, leaving the bottom half unused)
|
// TODO : Fix test-case Shenmue 2 (which halves height, leaving the bottom half unused)
|
||||||
HostViewPort.MinZ = XboxViewPort.MinZ; // No need scale Z for now
|
HostViewPort.MinZ = XboxViewPort.MinZ; // No need scale Z for now
|
||||||
HostViewPort.MaxZ = XboxViewPort.MaxZ;
|
HostViewPort.MaxZ = XboxViewPort.MaxZ;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
EmuLog(LOG_LEVEL::WARNING, "GetHostRenderTargetDimensions failed - SetViewport sets Xbox viewport instead!");
|
EmuLog(LOG_LEVEL::WARNING, "GetHostRenderTargetDimensions failed - SetViewport sets Xbox viewport instead!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue