CopyRects accounts for host resource scaling
Fixes Crash Tag Team Racing resolution scaling issue
This commit is contained in:
parent
ee6a61c364
commit
fc655cdca5
|
@ -4921,7 +4921,7 @@ VOID WINAPI xbox::EMUPATCH(D3DDevice_CopyRects)
|
|||
// We skip the trampoline to prevent unnecessary work
|
||||
// As our surfaces remain on the GPU, calling the trampoline would just
|
||||
// result in a memcpy from an empty Xbox surface to another empty Xbox Surface
|
||||
D3DSURFACE_DESC SourceDesc, DestinationDesc;
|
||||
D3DSURFACE_DESC hostSourceDesc, hostDestDesc;
|
||||
auto pHostSourceSurface = GetHostSurface(pSourceSurface);
|
||||
auto pHostDestSurface = GetHostSurface(pDestinationSurface);
|
||||
|
||||
|
@ -4932,16 +4932,16 @@ VOID WINAPI xbox::EMUPATCH(D3DDevice_CopyRects)
|
|||
return;
|
||||
}
|
||||
|
||||
pHostSourceSurface->GetDesc(&SourceDesc);
|
||||
pHostDestSurface->GetDesc(&DestinationDesc);
|
||||
pHostSourceSurface->GetDesc(&hostSourceDesc);
|
||||
pHostDestSurface->GetDesc(&hostDestDesc);
|
||||
|
||||
// If the source is a render-target and the destination is not, we need force it to be re-created as one
|
||||
// This is because StrechRects cannot copy from a Render-Target to a Non-Render Target
|
||||
// Test Case: Crash Bandicoot: Wrath of Cortex attemps to copy the render-target to a texture
|
||||
// This fixes an issue on the pause screen where the screenshot of the current scene was not displayed correctly
|
||||
if ((SourceDesc.Usage & D3DUSAGE_RENDERTARGET) != 0 && (DestinationDesc.Usage & D3DUSAGE_RENDERTARGET) == 0) {
|
||||
if ((hostSourceDesc.Usage & D3DUSAGE_RENDERTARGET) != 0 && (hostDestDesc.Usage & D3DUSAGE_RENDERTARGET) == 0) {
|
||||
pHostDestSurface = GetHostSurface(pDestinationSurface, D3DUSAGE_RENDERTARGET);
|
||||
pHostDestSurface->GetDesc(&DestinationDesc);
|
||||
pHostDestSurface->GetDesc(&hostDestDesc);
|
||||
}
|
||||
|
||||
// If no rectangles were given, default to 1 (entire surface)
|
||||
|
@ -4949,6 +4949,13 @@ VOID WINAPI xbox::EMUPATCH(D3DDevice_CopyRects)
|
|||
cRects = 1;
|
||||
}
|
||||
|
||||
// Get Xbox surface dimensions
|
||||
// Host resources may be scaled so we'll account for that later
|
||||
auto xboxSourceWidth = GetPixelContainerWidth(pSourceSurface);
|
||||
auto xboxSourceHeight = GetPixelContainerHeight(pSourceSurface);
|
||||
auto xboxDestWidth = GetPixelContainerWidth(pDestinationSurface);
|
||||
auto xboxDestHeight = GetPixelContainerHeight(pDestinationSurface);
|
||||
|
||||
for (UINT i = 0; i < cRects; i++) {
|
||||
RECT SourceRect, DestRect;
|
||||
|
||||
|
@ -4956,9 +4963,9 @@ VOID WINAPI xbox::EMUPATCH(D3DDevice_CopyRects)
|
|||
SourceRect = pSourceRectsArray[i];
|
||||
} else {
|
||||
SourceRect.left = 0;
|
||||
SourceRect.right = SourceDesc.Width;
|
||||
SourceRect.right = xboxSourceWidth;
|
||||
SourceRect.top = 0;
|
||||
SourceRect.bottom = SourceDesc.Height;
|
||||
SourceRect.bottom = xboxSourceHeight;
|
||||
}
|
||||
|
||||
if (pDestPointsArray != nullptr) {
|
||||
|
@ -4970,11 +4977,28 @@ VOID WINAPI xbox::EMUPATCH(D3DDevice_CopyRects)
|
|||
DestRect = SourceRect;
|
||||
} else {
|
||||
DestRect.left = 0;
|
||||
DestRect.right = DestinationDesc.Width;
|
||||
DestRect.right = xboxDestWidth;
|
||||
DestRect.top = 0;
|
||||
DestRect.bottom = DestinationDesc.Height;
|
||||
DestRect.bottom = xboxDestHeight;
|
||||
}
|
||||
|
||||
// Scale the source and destination rects
|
||||
auto sourceScaleX = (uint32_t)hostSourceDesc.Width / xboxSourceWidth;
|
||||
auto sourceScaleY = (uint32_t)hostSourceDesc.Height / xboxSourceHeight;
|
||||
|
||||
SourceRect.left *= sourceScaleX;
|
||||
SourceRect.right *= sourceScaleX;
|
||||
SourceRect.top *= sourceScaleY;
|
||||
SourceRect.bottom *= sourceScaleY;
|
||||
|
||||
auto destScaleX = (uint32_t) hostDestDesc.Width / xboxDestWidth;
|
||||
auto destScaleY = (uint32_t) hostDestDesc.Height / xboxDestHeight;
|
||||
|
||||
DestRect.left *= destScaleX;
|
||||
DestRect.right *= destScaleX;
|
||||
DestRect.top *= destScaleY;
|
||||
DestRect.bottom *= destScaleY;
|
||||
|
||||
HRESULT hRet = g_pD3DDevice->StretchRect(pHostSourceSurface, &SourceRect, pHostDestSurface, &DestRect, D3DTEXF_NONE);
|
||||
if (FAILED(hRet)) {
|
||||
LOG_TEST_CASE("D3DDevice_CopyRects: Failed to copy surface");
|
||||
|
|
Loading…
Reference in New Issue