Permalink
Browse files

Improve sanity checks for framebuffer readbacks

  • Loading branch information...
hrydgard committed Oct 28, 2018
1 parent 5807ad0 commit c074d3c61f8f031b7dbd2622314ad49406fd935e
Showing with 20 additions and 2 deletions.
  1. +17 −2 GPU/Common/FramebufferCommon.cpp
  2. +3 −0 ext/native/thin3d/GLRenderManager.cpp
@@ -2052,19 +2052,34 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int
return;
}
if (w <= 0 || h <= 0) {
ERROR_LOG(G3D, "Bad inputs to PackFramebufferSync_: %d %d %d %d", x, y, w, h);
return;
}
const u32 fb_address = (0x04000000) | vfb->fb_address;
Draw::DataFormat destFormat = GEFormatToThin3D(vfb->format);
const int dstBpp = (int)DataFormatSizeInBytes(destFormat);
const int dstByteOffset = (y * vfb->fb_stride + x) * dstBpp;
if (!Memory::IsValidRange(fb_address + dstByteOffset, (h * vfb->fb_stride + w) * dstBpp)) {
ERROR_LOG(G3D, "PackFramebufferSync_ would read outside of memory, ignoring");
return;
}
u8 *destPtr = Memory::GetPointer(fb_address + dstByteOffset);
// We always need to convert from the framebuffer native format.
// Right now that's always 8888.
DEBUG_LOG(G3D, "Reading framebuffer to mem, fb_address = %08x", fb_address);
DEBUG_LOG(G3D, "Reading framebuffer to mem, fb_address = %08x, ptr=%p", fb_address, destPtr);
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride);
if (destPtr) {
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride);
} else {
ERROR_LOG(G3D, "PackFramebufferSync_: Tried to readback to bad address %08x (stride = %d)", fb_address + dstByteOffset, vfb->fb_stride);
}
// A new command buffer will begin after CopyFrameBufferToMemorySync, so we need to trigger
// updates of any dynamic command buffer state by dirtying some stuff.
@@ -334,6 +334,8 @@ void GLRenderManager::BlitFramebuffer(GLRFramebuffer *src, GLRect2D srcRect, GLR
}
bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspectBits, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) {
_assert_(pixels);
GLRStep *step = new GLRStep{ GLRStepType::READBACK };
step->readback.src = src;
step->readback.srcRect = { x, y, w, h };
@@ -365,6 +367,7 @@ bool GLRenderManager::CopyFramebufferToMemorySync(GLRFramebuffer *src, int aspec
void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, int x, int y, int w, int h, Draw::DataFormat destFormat, uint8_t *pixels, int pixelStride) {
_assert_(texture);
_assert_(pixels);
GLRStep *step = new GLRStep{ GLRStepType::READBACK_IMAGE };
step->readback_image.texture = texture;
step->readback_image.mipLevel = mipLevel;

0 comments on commit c074d3c

Please sign in to comment.