From 8b46faed5036aa529c9239e09396c993640bf993 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 3 Jun 2014 22:51:16 -0700 Subject: [PATCH 1/4] Implement intra-buffer block transfer. --- GPU/GLES/Framebuffer.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index fd0cbe5a80..9e889e0c45 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -2048,12 +2048,29 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride if (dstBuffer && srcBuffer) { if (srcBuffer == dstBuffer) { - WARN_LOG_REPORT_ONCE(dstsrc, G3D, "Intra-buffer block transfer (not supported) %08x -> %08x", srcBasePtr, dstBasePtr); + if (srcX != dstX || srcY != dstY) { + WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); + if (g_Config.bBlockTransferGPU) { + FBO *tempFBO = GetTempFBO(dstBuffer->width, dstBuffer->height, dstBuffer->colorDepth); + VirtualFramebuffer tempBuffer = *dstBuffer; + tempBuffer.fbo = tempFBO; + BlitFramebuffer_(&tempBuffer, srcX, srcY, dstBuffer, srcX, srcY, width, height, bpp); + BlitFramebuffer_(dstBuffer, dstX, dstY, &tempBuffer, srcX, srcY, width, height, bpp); + RebindFramebuffer(); + return true; + } + } else { + // Ignore, nothing to do. Tales of Phantasia X does this by accident. + if (g_Config.bBlockTransferGPU) { + return true; + } + } } else { WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); // Just do the blit! if (g_Config.bBlockTransferGPU) { BlitFramebuffer_(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, width, height, bpp); + RebindFramebuffer(); return true; // No need to actually do the memory copy behind, probably. } } From 7839f39c13d7b805469f10730bf1e294eb8ae023 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 3 Jun 2014 22:52:32 -0700 Subject: [PATCH 2/4] Allow block xfer upload when using read fb to mem. --- GPU/GLES/Framebuffer.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 9e889e0c45..c17b38164a 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -2090,10 +2090,6 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride } void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp) { - if (updateVRAM_) { - return; - } - // A few games use this INSTEAD of actually drawing the video image to the screen, they just blast it to // the backbuffer. Detect this and have the framebuffermanager draw the pixels. From e67c2e7328220718b8f05f8ecb553463b9b44f5b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 3 Jun 2014 22:54:36 -0700 Subject: [PATCH 3/4] No need to report this anymore, hopefully. --- GPU/GLES/Framebuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index c17b38164a..255e753268 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -2114,7 +2114,7 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, } if (dstBuffer && !srcBuffer) { - WARN_LOG_REPORT_ONCE(btu, G3D, "Block transfer upload %08x -> %08x", srcBasePtr, dstBasePtr); + WARN_LOG_ONCE(btu, G3D, "Block transfer upload %08x -> %08x", srcBasePtr, dstBasePtr); if (g_Config.bBlockTransferGPU) { const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp; if (useBufferedRendering_) { From d111a8d3ff21efaf7cc14ab25cd79c74dce861c0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 4 Jun 2014 00:21:52 -0700 Subject: [PATCH 4/4] Remove video size hack when uploading fb data. Seems like this was only helping because we were stretching some framebuffers before, it only causes problems now. --- GPU/GLES/Framebuffer.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 255e753268..0c5e35e419 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -1875,19 +1875,7 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) { if (useBufferedRendering_ && vfb->fbo) { DisableState(); fbo_bind_as_render_target(vfb->fbo); - - int w = vfb->bufferWidth; - int h = vfb->bufferHeight; - // Often, the framebuffer size is incorrect. But here we have the size. Bit of a hack. - if (vfb->fb_stride == 512 && (size == 512 * 272 * 4 || size == 512 * 272 * 2)) { - // Looks like a standard 480x272 sized framebuffer/video/etc. - w = 480; - h = 272; - } - // Scale by the render resolution factor. - w = (w * vfb->renderWidth) / vfb->bufferWidth; - h = (h * vfb->renderHeight) / vfb->bufferHeight; - glstate.viewport.set(0, vfb->renderHeight - h, w, h); + glstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight); needUnbind = true; DrawPixels(vfb, 0, 0, Memory::GetPointer(addr | 0x04000000), vfb->format, vfb->fb_stride, vfb->width, vfb->height); } else {