Fix black screen in some titles when switching resolutions during gameplay
This contains a bug fix that can be seen on the MS dashboard (Clipped viewport values were never copied back to HostViewPort) And one that was a previously unknown behavior (changing backbuffer width/height without a call to SetRenderTarget) a LOG_TEST_CASE has been added for the new behavior, and a fix has been applied by destroying the existing host render target, and creating a new one. Known PR Test Cases: - MS Dashboard 'Video Mode' settings menu (When switching between 'widescreen', 'letterbox', 'normal') - Chihiro Factory Test Program (requires chihiro-work branch)
This commit is contained in:
parent
952e7870cd
commit
eec144e2e2
|
@ -3207,14 +3207,32 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetViewport)
|
|||
DWORD top = std::max((int)pViewport->Y, 0);
|
||||
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 width = right - left;
|
||||
DWORD height = bottom - top;
|
||||
|
||||
XboxViewPort.X = left;
|
||||
XboxViewPort.Y = top;
|
||||
XboxViewPort.Width = right - left;
|
||||
XboxViewPort.Height = bottom - top;
|
||||
XboxViewPort.Width = width;
|
||||
XboxViewPort.Height = height;
|
||||
XboxViewPort.MinZ = pViewport->MinZ;
|
||||
XboxViewPort.MaxZ = pViewport->MaxZ;
|
||||
|
||||
// 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");
|
||||
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;
|
||||
|
||||
if (g_ScaleViewport) {
|
||||
// Get current host render target dimensions
|
||||
DWORD HostRenderTarget_Width;
|
||||
|
|
Loading…
Reference in New Issue