Only copy dirty depth buffers between FBOs.

We can remove this if/when we track them separately.  This may break a
game that depends on the depth carrying over between several FBOs, but
that's not extremely likely.

This improves performance in Gods Eater Burst.
This commit is contained in:
Unknown W. Brackets 2014-01-24 01:44:24 -08:00
parent d69f02dea0
commit b034b992df
3 changed files with 21 additions and 2 deletions

View file

@ -744,7 +744,8 @@ void FramebufferManager::SetRenderFrameBuffer() {
vfb->dirtyAfterDisplay = true; vfb->dirtyAfterDisplay = true;
if ((gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0) if ((gstate_c.skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
vfb->reallyDirtyAfterDisplay = true; vfb->reallyDirtyAfterDisplay = true;
vfb->memoryUpdated = false; vfb->memoryUpdated = false;
vfb->depthUpdated = false;
if (g_Config.bTrueColor) { if (g_Config.bTrueColor) {
vfb->colorDepth = FBO_8888; vfb->colorDepth = FBO_8888;
@ -907,7 +908,13 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
if (!sourceframebuffer || !targetframebuffer->fbo || !useBufferedRendering_) { if (!sourceframebuffer || !targetframebuffer->fbo || !useBufferedRendering_) {
return; return;
} }
// If depth wasn't updated, then we're at least "two degrees" away from the data.
// This is an optimization: it probably doesn't need to be copied in this case.
if (!sourceframebuffer->depthUpdated) {
return;
}
if (MaskedEqual(sourceframebuffer->z_address, targetframebuffer->z_address) && if (MaskedEqual(sourceframebuffer->z_address, targetframebuffer->z_address) &&
sourceframebuffer->renderWidth == targetframebuffer->renderWidth && sourceframebuffer->renderWidth == targetframebuffer->renderWidth &&
sourceframebuffer->renderHeight == targetframebuffer->renderHeight) { sourceframebuffer->renderHeight == targetframebuffer->renderHeight) {
@ -923,6 +930,7 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf
if (!gstate.isModeClear() || !gstate.isClearModeDepthMask()) { if (!gstate.isModeClear() || !gstate.isClearModeDepthMask()) {
fbo_bind_for_read(sourceframebuffer->fbo); fbo_bind_for_read(sourceframebuffer->fbo);
glBlitFramebuffer(0, 0, sourceframebuffer->renderWidth, sourceframebuffer->renderHeight, 0, 0, targetframebuffer->renderWidth, targetframebuffer->renderHeight, GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, sourceframebuffer->renderWidth, sourceframebuffer->renderHeight, 0, 0, targetframebuffer->renderWidth, targetframebuffer->renderHeight, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// If we set targetframebuffer->depthUpdated here, our optimization above would be pointless.
} }
#endif #endif
} }

View file

@ -58,6 +58,7 @@ struct VirtualFramebuffer {
int last_frame_used; int last_frame_used;
int last_frame_render; int last_frame_render;
bool memoryUpdated; bool memoryUpdated;
bool depthUpdated;
u32 fb_address; u32 fb_address;
u32 z_address; u32 z_address;
@ -174,6 +175,12 @@ public:
return displayFramebuf_ ? (0x04000000 | displayFramebuf_->fb_address) : 0; return displayFramebuf_ ? (0x04000000 | displayFramebuf_->fb_address) : 0;
} }
void SetDepthUpdated() {
if (currentRenderVfb_) {
currentRenderVfb_->depthUpdated = true;
}
}
void NotifyFramebufferCopy(u32 src, u32 dest, int size); void NotifyFramebufferCopy(u32 src, u32 dest, int size);
void DestroyFramebuf(VirtualFramebuffer *vfb); void DestroyFramebuf(VirtualFramebuffer *vfb);

View file

@ -356,6 +356,9 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
glstate.depthTest.enable(); glstate.depthTest.enable();
glstate.depthFunc.set(GL_ALWAYS); glstate.depthFunc.set(GL_ALWAYS);
glstate.depthWrite.set(gstate.isClearModeDepthMask() || alwaysDepthWrite ? GL_TRUE : GL_FALSE); glstate.depthWrite.set(gstate.isClearModeDepthMask() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
framebufferManager_->SetDepthUpdated();
}
// Color Test // Color Test
bool colorMask = gstate.isClearModeColorMask(); bool colorMask = gstate.isClearModeColorMask();
@ -398,6 +401,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
glstate.depthTest.enable(); glstate.depthTest.enable();
glstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]); glstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE); glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
framebufferManager_->SetDepthUpdated();
} else { } else {
glstate.depthTest.disable(); glstate.depthTest.disable();
} }