diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 8545115e86..9cf359bfa9 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -224,7 +224,7 @@ public: virtual void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h); - virtual void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); + void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader); void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index dbfa48c1ad..9902871089 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -238,18 +238,7 @@ void FramebufferManagerGLES::BindPostShader(const PostShaderUniforms &uniforms) FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw, GLRenderManager *render) : FramebufferManagerCommon(draw), - render_(render), - drawPixelsTex_(0), - drawPixelsTexFormat_(GE_FORMAT_INVALID), - convBuf_(nullptr), - videoLoc_(-1), - timeLoc_(-1), - pixelDeltaLoc_(-1), - deltaLoc_(-1), - textureCacheGL_(nullptr), - shaderManagerGL_(nullptr), - pixelBufObj_(nullptr), - currentPBO_(0) + render_(render) { needBackBufferYSwap_ = true; needGLESRebinds_ = true; @@ -315,14 +304,6 @@ void FramebufferManagerGLES::DestroyDeviceObjects() { FramebufferManagerGLES::~FramebufferManagerGLES() { DestroyDeviceObjects(); - if (pixelBufObj_) { - for (int i = 0; i < MAX_PBO; i++) { - if (pixelBufObj_[i].buffer) { - render_->DeleteBuffer(pixelBufObj_[i].buffer); - } - } - delete[] pixelBufObj_; - } delete [] convBuf_; } @@ -540,46 +521,19 @@ void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFra void FramebufferManagerGLES::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { PROFILE_THIS_SCOPE("gpu-readback"); - if (sync) { - // flush async just in case when we go for synchronous update - // Doesn't actually pack when sent a null argument. - PackFramebufferAsync_(nullptr); - } - if (vfb) { // We'll pseudo-blit framebuffers here to get a resized version of vfb. VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb); OptimizeDownloadRange(vfb, x, y, w, h); BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0); - // PackFramebufferSync_() - Synchronous pixel data transfer using glReadPixels - // PackFramebufferAsync_() - Asynchronous pixel data transfer using glReadPixels with PBOs - - if (gl_extensions.IsGLES) { - PackFramebufferSync_(nvfb, x, y, w, h); - } else { - // TODO: Can we fall back to sync without these? - if (gl_extensions.ARB_pixel_buffer_object && gstate_c.Supports(GPU_SUPPORTS_OES_TEXTURE_NPOT)) { - if (!sync) { - PackFramebufferAsync_(nvfb); - } else { - PackFramebufferSync_(nvfb, x, y, w, h); - } - } - } + PackFramebufferSync_(nvfb, x, y, w, h); textureCacheGL_->ForgetLastTexture(); RebindFramebuffer(); } } -void FramebufferManagerGLES::DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) { - PROFILE_THIS_SCOPE("gpu-readback"); - // Flush async just in case. - PackFramebufferAsync_(nullptr); - FramebufferManagerCommon::DownloadFramebufferForClut(fb_address, loadBytes); -} - bool FramebufferManagerGLES::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) { // When updating VRAM, it need to be exact format. if (!gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD)) { @@ -758,117 +712,6 @@ void ConvertFromRGBA8888(u8 *dst, const u8 *src, u32 dstStride, u32 srcStride, u } } -void FramebufferManagerGLES::PackFramebufferAsync_(VirtualFramebuffer *vfb) { - GLubyte *packed = 0; - bool unbind = false; - const u8 nextPBO = (currentPBO_ + 1) % MAX_PBO; - const bool useCPU = gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD); - - // We'll prepare two PBOs to switch between readying and reading - if (!pixelBufObj_) { - if (!vfb) { - // This call is just to flush the buffers. We don't have any yet, - // so there's nothing to do. - return; - } - - pixelBufObj_ = new AsyncPBO[MAX_PBO]{}; - } - - // Receive previously requested data from a PBO - AsyncPBO &pbo = pixelBufObj_[nextPBO]; - if (pbo.reading) { - render_->BindPixelPackBuffer(pbo.buffer); -#ifdef USING_GLES2 - // Not on desktop GL 2.x... - packed = (GLubyte *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pbo.size, GL_MAP_READ_BIT); -#else - packed = (GLubyte *)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); -#endif - - if (packed) { - DEBUG_LOG(FRAMEBUF, "Reading PBO to memory , bufSize = %u, packed = %p, fb_address = %08x, stride = %u, pbo = %u", - pbo.size, packed, pbo.fb_address, pbo.stride, nextPBO); - - if (useCPU) { - u8 *dst = Memory::GetPointer(pbo.fb_address); - ConvertFromRGBA8888(dst, packed, pbo.stride, pbo.stride, pbo.stride, pbo.height, pbo.format); - } else { - // We don't need to convert, GPU already did (or should have) - Memory::MemcpyUnchecked(pbo.fb_address, packed, pbo.size); - } - - pbo.reading = false; - } - - glUnmapBuffer(GL_PIXEL_PACK_BUFFER); - unbind = true; - } - - // Order packing/readback of the framebuffer - if (vfb) { - bool reverseOrder = gstate_c.Supports(GPU_PREFER_REVERSE_COLOR_ORDER); - Draw::DataFormat dataFmt = Draw::DataFormat::UNDEFINED; - switch (vfb->format) { - case GE_FORMAT_4444: - dataFmt = (reverseOrder ? Draw::DataFormat::A4R4G4B4_UNORM_PACK16 : Draw::DataFormat::B4G4R4A4_UNORM_PACK16); - break; - case GE_FORMAT_5551: - dataFmt = (reverseOrder ? Draw::DataFormat::A1R5G5B5_UNORM_PACK16 : Draw::DataFormat::B5G5R5A1_UNORM_PACK16); - break; - case GE_FORMAT_565: - dataFmt = (reverseOrder ? Draw::DataFormat::R5G6B5_UNORM_PACK16 : Draw::DataFormat::B5G6R5_UNORM_PACK16); - break; - case GE_FORMAT_8888: - dataFmt = Draw::DataFormat::R8G8B8A8_UNORM; - break; - }; - - if (useCPU) { - dataFmt = Draw::DataFormat::R8G8B8A8_UNORM; - } - - int pixelSize = (int)DataFormatSizeInBytes(dataFmt); - int align = pixelSize; - - // If using the CPU, we need 4 bytes per pixel always. - u32 bufSize = vfb->fb_stride * vfb->height * pixelSize; - u32 fb_address = (0x04000000) | vfb->fb_address; - - if (!vfb->fbo) { - ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferAsync_: vfb->fbo == 0"); - return; - } - - if (pixelBufObj_[currentPBO_].maxSize < bufSize) { - if (pixelBufObj_[currentPBO_].buffer) { - render_->DeleteBuffer(pixelBufObj_[currentPBO_].buffer); - } - pixelBufObj_[currentPBO_].buffer = render_->CreateBuffer(GL_PIXEL_PACK_BUFFER, bufSize, GL_DYNAMIC_READ); - pixelBufObj_[currentPBO_].maxSize = bufSize; - } - - render_->BindPixelPackBuffer(pixelBufObj_[currentPBO_].buffer); - // TODO: This is a hack since PBOs have not been implemented in Thin3D yet (and maybe shouldn't? maybe should do this internally?) - draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, 0, 0, vfb->fb_stride, vfb->height, dataFmt, nullptr, vfb->fb_stride); - - unbind = true; - - pixelBufObj_[currentPBO_].fb_address = fb_address; - pixelBufObj_[currentPBO_].size = bufSize; - pixelBufObj_[currentPBO_].stride = vfb->fb_stride; - pixelBufObj_[currentPBO_].height = vfb->height; - pixelBufObj_[currentPBO_].format = vfb->format; - pixelBufObj_[currentPBO_].reading = true; - } - - currentPBO_ = nextPBO; - - if (unbind) { - render_->BindPixelPackBuffer(0); - } -} - void FramebufferManagerGLES::PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) { if (!vfb->fbo) { ERROR_LOG_REPORT_ONCE(vfbfbozero, SCEGE, "PackFramebufferSync_: vfb->fbo == 0"); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 60c5c841ad..969194babb 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -36,19 +36,6 @@ class TextureCacheGLES; class DrawEngineGLES; class ShaderManagerGLES; -// Simple struct for asynchronous PBO readbacks -struct AsyncPBO { - GLRBuffer *buffer; - u32 maxSize; - - u32 fb_address; - u32 stride; - u32 height; - u32 size; - GEBufferFormat format; - bool reading; -}; - class FramebufferManagerGLES : public FramebufferManagerCommon { public: FramebufferManagerGLES(Draw::DrawContext *draw, GLRenderManager *render); @@ -67,7 +54,6 @@ public: void EndFrame(); void Resized() override; void DeviceLost(); - void SetLineWidth(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; @@ -77,7 +63,6 @@ public: // Reads a rectangular subregion of a framebuffer to the right position in its backing memory. void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) override; - void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) override; bool NotifyStencilUpload(u32 addr, int size, bool skipZero = false) override; @@ -105,24 +90,22 @@ private: void CompileDraw2DProgram(); void CompilePostShader(); - void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h) override; void PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, int w, int h); GLRenderManager *render_; // Used by DrawPixels - GLRTexture *drawPixelsTex_; - GEBufferFormat drawPixelsTexFormat_; - int drawPixelsTexW_; - int drawPixelsTexH_; + GLRTexture *drawPixelsTex_ = nullptr; + GEBufferFormat drawPixelsTexFormat_ = GE_FORMAT_INVALID; + int drawPixelsTexW_ = 0; + int drawPixelsTexH_ = 0; - u8 *convBuf_; - u32 convBufSize_; + u8 *convBuf_ = nullptr; + u32 convBufSize_ = 0; GLRProgram *draw2dprogram_ = nullptr; GLRProgram *postShaderProgram_ = nullptr; - GLRProgram *stencilUploadProgram_ = nullptr; int u_stencilUploadTex = -1; int u_stencilValue = -1; @@ -137,17 +120,13 @@ private: int pixelDeltaLoc_ = -1; int deltaLoc_ = -1; - TextureCacheGLES *textureCacheGL_; - ShaderManagerGLES *shaderManagerGL_; - DrawEngineGLES *drawEngineGL_; + TextureCacheGLES *textureCacheGL_ = nullptr; + ShaderManagerGLES *shaderManagerGL_ = nullptr; + DrawEngineGLES *drawEngineGL_ = nullptr; struct Simple2DVertex { float pos[3]; float uv[2]; }; - GLRInputLayout *simple2DInputLayout_; - - // Not used under ES currently. - AsyncPBO *pixelBufObj_; //this isn't that large - u8 currentPBO_; + GLRInputLayout *simple2DInputLayout_ = nullptr; };