From 3f8ef6dacd8f5dde6c8f4e4b1eaac464becfe92b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 7 Jun 2014 22:40:41 -0700 Subject: [PATCH] Ensure stride in bytes matches FBO up/download. Even if we should do the copy, we'll currntly use the wrong x/y/w/h. This fixes incorrect uploads in God of War, which hurt performance a lot. Unfortunately, in this game there's zero information to tell us the right size of some small temp framebuffers it uses, so we overestimate their sizes and the block transfer appears to fall into range. --- GPU/GLES/Framebuffer.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 882b4a1903..25f366741e 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -2085,8 +2085,11 @@ void FramebufferManager::FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer const u32 vfb_size = FramebufferByteSize(vfb); if (vfb_address <= dstBasePtr && dstBasePtr < vfb_address + vfb_size) { const u32 byteOffset = dstBasePtr - vfb_address; - const u32 yOffset = byteOffset / (dstStride * bpp); - if (yOffset < dstYOffset) { + const u32 byteStride = dstStride * bpp; + const u32 yOffset = byteOffset / byteStride; + // Some games use mismatching bitdepths. But make sure the stride matches. + // If it doesn't, generally this means we detected the framebuffer with too large a height. + if (yOffset < dstYOffset && vfb_size / vfb->height == byteStride) { dstYOffset = yOffset; dstXOffset = (byteOffset / bpp) % dstStride; dstBuffer = vfb; @@ -2094,8 +2097,9 @@ void FramebufferManager::FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer } if (vfb_address <= srcBasePtr && srcBasePtr < vfb_address + vfb_size) { const u32 byteOffset = srcBasePtr - vfb_address; - const u32 yOffset = byteOffset / (srcStride * bpp); - if (yOffset < srcYOffset) { + const u32 byteStride = srcStride * bpp; + const u32 yOffset = byteOffset / byteStride; + if (yOffset < srcYOffset && vfb_size / vfb->height == byteStride) { srcYOffset = yOffset; srcXOffset = (byteOffset / bpp) % srcStride; srcBuffer = vfb;