Some preparations towards framebuffer management improvements

This commit is contained in:
Henrik Rydgard 2014-05-08 14:26:17 +02:00
parent d3ab35673b
commit 8ef377c427
3 changed files with 42 additions and 29 deletions

View file

@ -1231,7 +1231,7 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
}
}
void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool flip, float upscale, float vscale) {
void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *src, VirtualFramebuffer *dst, bool flip, float uscale, float vscale) {
if (dst->fbo) {
fbo_bind_as_render_target(dst->fbo);
} else {
@ -1260,12 +1260,13 @@ void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *src, VirtualFrameb
return;
}
// It's pretty obvious that this CenterRect is incorrect.
float x, y, w, h;
CenterRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight);
CompileDraw2DProgram();
DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, flip, upscale, vscale, draw2dprogram_);
DrawActiveTexture(0, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, flip, uscale, vscale, draw2dprogram_);
glBindTexture(GL_TEXTURE_2D, 0);
fbo_unbind();
@ -1572,8 +1573,10 @@ void FramebufferManager::EndFrame() {
}
#ifndef USING_GLES2
// We flush to memory last requested framebuffer, if any
PackFramebufferAsync_(NULL);
// We flush to memory last requested framebuffer, if any.
// Only do this in the read-framebuffer modes.
if (g_Config.iRenderingMode == FB_READFBOMEMORY_CPU || g_Config.iRenderingMode == FB_READFBOMEMORY_GPU)
PackFramebufferAsync_(NULL);
#endif
}
@ -1726,34 +1729,35 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) {
}
}
void FramebufferManager::NotifyBlockTransfer(u32 dst, u32 src) {
bool FramebufferManager::NotifyBlockTransfer(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h) {
// The stuff in the #ifdef is JUST for reporting, not used for anything else.
#ifndef MOBILE_DEVICE
if (!reportedBlits_.insert(std::make_pair(dst, src)).second) {
if (reportedBlits_.insert(std::make_pair(dstBasePtr, srcBasePtr)).second) {
// Already reported/checked.
return;
}
bool dstBuffer = false;
bool srcBuffer = false;
for (size_t i = 0; i < vfbs_.size(); ++i) {
VirtualFramebuffer *vfb = vfbs_[i];
if (MaskedEqual(vfb->fb_address, dst)) {
dstBuffer = true;
bool dstBuffer = false;
bool srcBuffer = false;
for (size_t i = 0; i < vfbs_.size(); ++i) {
VirtualFramebuffer *vfb = vfbs_[i];
if (MaskedEqual(vfb->fb_address, dstBasePtr)) {
dstBuffer = true;
}
if (MaskedEqual(vfb->fb_address, srcBasePtr)) {
srcBuffer = true;
}
}
if (MaskedEqual(vfb->fb_address, src)) {
srcBuffer = true;
if (dstBuffer && srcBuffer) {
WARN_LOG_REPORT(G3D, "Intra buffer block transfer (not supported) %08x -> %08x", srcBasePtr, dstBasePtr);
} else if (dstBuffer) {
WARN_LOG_REPORT(G3D, "Block transfer upload (not supported) %08x -> %08x", srcBasePtr, dstBasePtr);
} else if (srcBuffer && g_Config.iRenderingMode == FB_BUFFERED_MODE) {
WARN_LOG_REPORT(G3D, "Block transfer download (not supported) %08x -> %08x", srcBasePtr, dstBasePtr);
}
}
if (dstBuffer && srcBuffer) {
WARN_LOG_REPORT(G3D, "Intra buffer block transfer (not supported) %08x -> %08x", src, dst);
} else if (dstBuffer) {
WARN_LOG_REPORT(G3D, "Block transfer upload (not supported) %08x -> %08x", src, dst);
} else if (srcBuffer && g_Config.iRenderingMode == FB_BUFFERED_MODE) {
WARN_LOG_REPORT(G3D, "Block transfer download (not supported) %08x -> %08x", src, dst);
}
#endif
return false;
}
void FramebufferManager::Resized() {

View file

@ -159,8 +159,10 @@ public:
// For use when texturing from a framebuffer. May create a duplicate if target.
void BindFramebufferColor(VirtualFramebuffer *framebuffer);
// Just for logging right now. Might remove/change.
void NotifyBlockTransfer(u32 dst, u32 src);
// 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);
#ifdef USING_GLES2
void ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync = true);
@ -262,5 +264,7 @@ private:
u8 currentPBO_;
#endif
// This is to be used only for reporting of strange blits. Don't control behaviour as
// this is "permanent" while framebuffers aren't.
std::set<std::pair<u32, u32>> reportedBlits_;
};

View file

@ -1929,8 +1929,10 @@ void GLES_GPU::DoBlockTransfer() {
}
}
// TODO: Notify all overlapping FBOs that they need to reload.
framebufferManager_.NotifyBlockTransfer(dstBasePtr, srcBasePtr);
// 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;
}
textureCache_.Invalidate(dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, GPU_INVALIDATE_HINT);
if (Memory::IsRAMAddress(srcBasePtr) && Memory::IsVRAMAddress(dstBasePtr)) {
@ -1953,9 +1955,12 @@ void GLES_GPU::DoBlockTransfer() {
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
}