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:
parent
d69f02dea0
commit
b034b992df
3 changed files with 21 additions and 2 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue