BlockTransfer: Move framebuffer handling into Framebuffer.cpp

This commit is contained in:
Henrik Rydgard 2014-05-08 14:54:45 +02:00
parent 8ef377c427
commit 5a60ccc9f0
3 changed files with 24 additions and 28 deletions

View File

@ -1729,7 +1729,27 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) {
}
}
bool FramebufferManager::NotifyBlockTransfer(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h) {
bool FramebufferManager::NotifyBlockTransfer(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int width, int height, int bpp) {
if (Memory::IsRAMAddress(srcBasePtr) && Memory::IsVRAMAddress(dstBasePtr)) {
// TODO: This causes glitches in Tactics Ogre if we don't implement both ways (which will probably be slow...)
// The main thing this helps is videos, which will have a matching stride, and zero x/y.
if (dstStride == srcStride && dstY == 0 && dstX == 0 && srcX == 0 && srcY == 0) {
UpdateFromMemory(dstBasePtr, (dstY + height) * dstStride * bpp, true);
}
}
// 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.
u32 backBuffer = PrevDisplayFramebufAddr();
u32 displayBuffer = DisplayFramebufAddr();
if (((backBuffer != 0 && dstBasePtr == backBuffer) ||
(displayBuffer != 0 && dstBasePtr == displayBuffer)) &&
dstStride == 512 && height == 272) {
DrawPixels(Memory::GetPointerUnchecked(dstBasePtr), GE_FORMAT_8888, 512);
}
// The stuff in the #ifdef is JUST for reporting, not used for anything else.
#ifndef MOBILE_DEVICE
if (reportedBlits_.insert(std::make_pair(dstBasePtr, srcBasePtr)).second) {

View File

@ -162,7 +162,7 @@ public:
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
// read framebuffers is on, in which case this should always return false).
bool NotifyBlockTransfer(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h);
bool NotifyBlockTransfer(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp);
#ifdef USING_GLES2
void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync = true);

View File

@ -1930,37 +1930,13 @@ void GLES_GPU::DoBlockTransfer() {
}
// Tell the framebuffer manager to take action if possible. If it does the entire thing, let's just return.
if (framebufferManager_.NotifyBlockTransfer(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height)) {
goto doMemChecks;
}
if (!framebufferManager_.NotifyBlockTransfer(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp)) {
textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
if (Memory::IsRAMAddress(srcBasePtr) && Memory::IsVRAMAddress(dstBasePtr)) {
// TODO: This causes glitches in Tactics Ogre if we don't implement both ways (which will probably be slow...)
// The main thing this helps is videos, which will have a matching stride, and zero x/y.
if (dstStride == srcStride && dstY == 0 && dstX == 0 && srcX == 0 && srcY == 0) {
framebufferManager_.UpdateFromMemory(dstBasePtr, (dstY + height) * dstStride * bpp, true);
}
}
// 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.
u32 backBuffer = framebufferManager_.PrevDisplayFramebufAddr();
u32 displayBuffer = framebufferManager_.DisplayFramebufAddr();
if (((backBuffer != 0 && dstBasePtr == backBuffer) ||
(displayBuffer != 0 && dstBasePtr == displayBuffer)) &&
dstStride == 512 && height == 272) {
framebufferManager_.DrawPixels(Memory::GetPointerUnchecked(dstBasePtr), GE_FORMAT_8888, 512);
}
doMemChecks:
#ifndef MOBILE_DEVICE
CBreakPoints::ExecMemCheck(srcBasePtr + (srcY * srcStride + srcX) * bpp, false, height * srcStride * bpp, currentMIPS->pc);
CBreakPoints::ExecMemCheck(dstBasePtr + (srcY * dstStride + srcX) * bpp, true, height * dstStride * bpp, currentMIPS->pc);
#else
;
#endif
}