From 49f830d88c884c2677a487d8df1852af91aa272e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 3 Feb 2023 13:19:00 +0100 Subject: [PATCH] Small refactor --- GPU/Common/FramebufferManagerCommon.cpp | 28 ++++++++++++------------- GPU/Common/FramebufferManagerCommon.h | 6 +++++- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index de73d52e29..c0a061f5f4 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -2717,19 +2717,14 @@ bool FramebufferManagerCommon::GetOutputFramebuffer(GPUDebugBuffer &buffer) { // (Except using the GPU might cause problems because of various implementations' // dithering behavior and games that expect exact colors like Danganronpa, so we // can't entirely be rid of the CPU path.) -- unknown -void FramebufferManagerCommon::ReadbackFramebufferSync(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel) { +void FramebufferManagerCommon::ReadbackFramebufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, RasterChannel channel, Draw::DataFormat destFormat, u32 fb_address, u32 stride) { if (w <= 0 || h <= 0) { ERROR_LOG(G3D, "Bad inputs to ReadbackFramebufferSync: %d %d %d %d", x, y, w, h); return; } - const u32 fb_address = channel == RASTER_COLOR ? vfb->fb_address : vfb->z_address; - - Draw::DataFormat destFormat = channel == RASTER_COLOR ? GEFormatToThin3D(vfb->fb_format) : GEFormatToThin3D(GE_FORMAT_DEPTH16); const int dstBpp = (int)DataFormatSizeInBytes(destFormat); - int stride = channel == RASTER_COLOR ? vfb->fb_stride : vfb->z_stride; - const int dstByteOffset = (y * stride + x) * dstBpp; // Leave the gap between the end of the last line and the full stride. // This is only used for the NotifyMemInfo range. @@ -2747,14 +2742,14 @@ void FramebufferManagerCommon::ReadbackFramebufferSync(VirtualFramebuffer *vfb, DEBUG_LOG(G3D, "Reading framebuffer to mem, fb_address = %08x, ptr=%p", fb_address, destPtr); if (channel == RASTER_DEPTH) { - _assert_msg_(vfb && vfb->z_address != 0 && vfb->z_stride != 0, "Depth buffer invalid"); - ReadbackDepthbufferSync(vfb->fbo, x, y, w, h, (uint16_t *)destPtr, stride); + // _assert_msg_(vfb && vfb->z_address != 0 && vfb->z_stride != 0, "Depth buffer invalid"); + ReadbackDepthbufferSync(fbo, x, y, w, h, (uint16_t *)destPtr, stride); } else { - draw_->CopyFramebufferToMemorySync(vfb->fbo, channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, x, y, w, h, destFormat, destPtr, stride, "ReadbackFramebufferSync"); + draw_->CopyFramebufferToMemorySync(fbo, channel == RASTER_COLOR ? Draw::FB_COLOR_BIT : Draw::FB_DEPTH_BIT, x, y, w, h, destFormat, destPtr, stride, "ReadbackFramebufferSync"); } char tag[128]; - size_t len = snprintf(tag, sizeof(tag), "FramebufferPack/%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, w, h, GeBufferFormatToString(vfb->fb_format)); + size_t len = snprintf(tag, sizeof(tag), "FramebufferPack/%08x_%dx%d", fb_address, w, h); NotifyMemInfo(MemBlockFlags::WRITE, fb_address + dstByteOffset, dstSize, tag, len); gpuStats.numReadbacks++; @@ -2807,14 +2802,19 @@ void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb, } } + u32 address = vfb->Address(channel); + int stride = vfb->Stride(channel); + + Draw::DataFormat destFormat = channel == RASTER_COLOR ? GEFormatToThin3D(vfb->fb_format) : GEFormatToThin3D(GE_FORMAT_DEPTH16); + if (vfb->renderWidth == vfb->width && vfb->renderHeight == vfb->height) { // No need to stretch-blit - ReadbackFramebufferSync(vfb, x, y, w, h, channel); + ReadbackFramebufferSync(vfb->fbo, x, y, w, h, channel, destFormat, address, stride); } else { VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb, channel); if (nvfb) { BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0, channel, "Blit_ReadFramebufferToMemory"); - ReadbackFramebufferSync(nvfb, x, y, w, h, channel); + ReadbackFramebufferSync(nvfb->fbo, x, y, w, h, channel, destFormat, address, stride); } } @@ -2837,7 +2837,7 @@ void FramebufferManagerCommon::FlushBeforeCopy() { } } -// TODO: Replace with with depal, reading the palette from the texture on the GPU directly. +// In practice, this has been replaced with depal, reading the palette from the texture on the GPU directly. void FramebufferManagerCommon::DownloadFramebufferForClut(u32 fb_address, u32 loadBytes) { VirtualFramebuffer *vfb = GetVFBAt(fb_address); if (vfb && vfb->fb_stride != 0) { @@ -2871,7 +2871,7 @@ void FramebufferManagerCommon::DownloadFramebufferForClut(u32 fb_address, u32 lo VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb, RASTER_COLOR); if (nvfb) { BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0, RASTER_COLOR, "Blit_DownloadFramebufferForClut"); - ReadbackFramebufferSync(nvfb, x, y, w, h, RASTER_COLOR); + ReadbackFramebufferSync(nvfb->fbo, x, y, w, h, RASTER_COLOR, GEFormatToThin3D(nvfb->fb_format), nvfb->fb_address, nvfb->fb_stride); } textureCache_->ForgetLastTexture(); diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index 4f0212f8cd..3a8232b431 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -152,6 +152,9 @@ struct VirtualFramebuffer { inline int BufferWidthInBytes() const { return bufferWidth * BufferFormatBytesPerPixel(fb_format); } inline int FbStrideInBytes() const { return fb_stride * BufferFormatBytesPerPixel(fb_format); } inline int ZStrideInBytes() const { return z_stride * 2; } + + inline u32 Address(RasterChannel channel) const { return channel == RASTER_COLOR ? fb_address : z_address; } + inline int Stride(RasterChannel channel) const { return channel == RASTER_COLOR ? fb_stride : z_stride; } }; struct FramebufferHeuristicParams { @@ -451,7 +454,8 @@ public: } protected: - virtual void ReadbackFramebufferSync(VirtualFramebuffer *vfb, int x, int y, int w, int h, RasterChannel channel); + void ReadbackFramebufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, RasterChannel channel, Draw::DataFormat destFormat, u32 fb_address, u32 stride); + // Used for when a shader is required, such as GLES. virtual bool ReadbackDepthbufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint16_t *pixels, int pixelsStride); virtual bool ReadbackStencilbufferSync(Draw::Framebuffer *fbo, int x, int y, int w, int h, uint8_t *pixels, int pixelsStride);