From c49ba888b54f89a3ded1a2f3078df77c3c30b438 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 11 Jun 2014 00:28:28 -0700 Subject: [PATCH] Flush draws before doing any block transfers. Otherwise, we might flush on top, or we might download the wrong thing. --- GPU/GLES/Framebuffer.cpp | 16 ++++++++++++++++ GPU/GLES/Framebuffer.h | 9 +++++++-- GPU/GLES/GLES_GPU.cpp | 7 +++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 2944869014..3667577ed5 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -39,6 +39,7 @@ #include "GPU/Common/TextureDecoder.h" #include "GPU/GLES/Framebuffer.h" #include "GPU/GLES/TextureCache.h" +#include "GPU/GLES/TransformPipeline.h" #include "GPU/GLES/ShaderManager.h" #include "UI/OnScreenDisplay.h" @@ -1963,6 +1964,7 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) { for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; if (MaskedEqual(vfb->fb_address, addr)) { + FlushBeforeCopy(); fbo_unbind(); currentRenderVfb_ = 0; @@ -2047,6 +2049,7 @@ bool FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool } else if (dstBuffer) { WARN_LOG_REPORT_ONCE(btucpy, G3D, "Memcpy fbo upload %08x -> %08x", src, dst); if (g_Config.bBlockTransferGPU) { + FlushBeforeCopy(); const u8 *srcBase = Memory::GetPointerUnchecked(src); if (useBufferedRendering_ && dstBuffer->fbo) { fbo_bind_as_render_target(dstBuffer->fbo); @@ -2080,6 +2083,7 @@ bool FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool h = srcBuffer->height; } if (h > 0) { + FlushBeforeCopy(); ReadFramebufferToMemory(srcBuffer, true, 0, 0, srcBuffer->width, h); } } @@ -2176,6 +2180,13 @@ void FramebufferManager::FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer } } +void FramebufferManager::FlushBeforeCopy() { + // Flush anything not yet drawn before blitting, downloading, or uploading. + // This might be a stalled list, or unflushed before a block transfer, etc. + SetRenderFrameBuffer(); + transformDraw_->Flush(); +} + bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp) { if (!useBufferedRendering_ || updateVRAM_) { return false; @@ -2199,6 +2210,7 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride if (srcX != dstX || srcY != dstY) { WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); if (g_Config.bBlockTransferGPU) { + FlushBeforeCopy(); FBO *tempFBO = GetTempFBO(dstBuffer->renderWidth, dstBuffer->renderHeight, dstBuffer->colorDepth); VirtualFramebuffer tempBuffer = *dstBuffer; tempBuffer.fbo = tempFBO; @@ -2217,6 +2229,7 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr); // Just do the blit! if (g_Config.bBlockTransferGPU) { + FlushBeforeCopy(); BlitFramebuffer_(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp); RebindFramebuffer(); return true; // No need to actually do the memory copy behind, probably. @@ -2231,6 +2244,7 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride if (g_Config.bBlockTransferGPU && (srcBuffer == currentRenderVfb_ || !srcBuffer->memoryUpdated)) { int srcBpp = srcBuffer->format == GE_FORMAT_8888 ? 4 : 2; float srcXFactor = (float)bpp / srcBpp; + FlushBeforeCopy(); ReadFramebufferToMemory(srcBuffer, true, srcX * srcXFactor, srcY, srcWidth * srcXFactor, srcHeight); } return false; // Let the bit copy happen @@ -2250,6 +2264,7 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, if (((backBuffer != 0 && dstBasePtr == backBuffer) || (displayBuffer != 0 && dstBasePtr == displayBuffer)) && dstStride == 512 && height == 272 && !useBufferedRendering_) { + FlushBeforeCopy(); DrawFramebuffer(Memory::GetPointerUnchecked(dstBasePtr), displayFormat_, 512, false); } @@ -2269,6 +2284,7 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, if (dstBuffer && !srcBuffer) { WARN_LOG_ONCE(btu, G3D, "Block transfer upload %08x -> %08x", srcBasePtr, dstBasePtr); if (g_Config.bBlockTransferGPU) { + FlushBeforeCopy(); const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp; if (useBufferedRendering_ && dstBuffer->fbo) { fbo_bind_as_render_target(dstBuffer->fbo); diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 1e85d65207..7760de50f9 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -33,6 +33,8 @@ struct GLSLProgram; class TextureCache; +class TransformDrawEngine; +class ShaderManager; enum { FB_USAGE_DISPLAYED_FRAMEBUFFER = 1, @@ -110,8 +112,6 @@ struct AsyncPBO { #endif -class ShaderManager; - class FramebufferManager { public: FramebufferManager(); @@ -123,6 +123,9 @@ public: void SetShaderManager(ShaderManager *sm) { shaderManager_ = sm; } + void SetTransformDrawEngine(TransformDrawEngine *td) { + transformDraw_ = td; + } void MakePixelTexture(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); @@ -232,6 +235,7 @@ public: private: void CompileDraw2DProgram(); void DestroyDraw2DProgram(); + void FlushBeforeCopy(); void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp) const; u32 FramebufferByteSize(const VirtualFramebuffer *vfb) const; @@ -280,6 +284,7 @@ private: TextureCache *textureCache_; ShaderManager *shaderManager_; + TransformDrawEngine *transformDraw_; bool usePostShader_; bool postShaderAtOutputResolution_; diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index f53ddef8ef..3d14b41a5b 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -409,6 +409,7 @@ GLES_GPU::GLES_GPU() transformDraw_.SetFramebufferManager(&framebufferManager_); framebufferManager_.SetTextureCache(&textureCache_); framebufferManager_.SetShaderManager(shaderManager_); + framebufferManager_.SetTransformDrawEngine(&transformDraw_); textureCache_.SetFramebufferManager(&framebufferManager_); textureCache_.SetDepalShaderCache(&depalShaderCache_); textureCache_.SetShaderManager(shaderManager_); @@ -603,11 +604,13 @@ void GLES_GPU::CopyDisplayToOutput() { } void GLES_GPU::CopyDisplayToOutputInternal() { + // Flush anything left over. + framebufferManager_.SetRenderFrameBuffer(); + transformDraw_.Flush(); + glstate.depthWrite.set(GL_TRUE); glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - transformDraw_.Flush(); - framebufferManager_.CopyDisplayToOutput(); framebufferManager_.EndFrame();