mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-10 21:16:24 +02:00
Defer depth copies until depth buffer is actually used.
Fixes
This commit is contained in:
1 parent
21cf6a6f04
commit
a0ac2dffc7
4 files changed
+45
-24
No files matched your search
@@ -377,6 +377,11 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
//
|
||||
// We use a special fragment shader flag to convert color to depth.
|
||||
vfb = GetLatestDepthBufferAt(params.fb_address /* !!! */, params.fb_stride);
|
||||
if (vfb) {
|
||||
vfb->depthBindSeq = GetBindSeqCount();
|
||||
}
|
||||
// Avoid causing another depth copy on top.
|
||||
gstate_c.usingDepth = true;
|
||||
}
|
||||
|
||||
gstate_c.SetFramebufferRenderMode(mode);
|
||||
@@ -416,6 +421,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
|
||||
// None found? Create one.
|
||||
if (!vfb) {
|
||||
gstate_c.usingDepth = false; // reset depth buffer tracking
|
||||
|
||||
vfb = new VirtualFramebuffer{};
|
||||
vfb->fbo = nullptr;
|
||||
vfb->fb_address = params.fb_address;
|
||||
@@ -442,17 +449,6 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
ResizeFramebufFBO(vfb, drawing_width, drawing_height, true);
|
||||
NotifyRenderFramebufferCreated(vfb);
|
||||
|
||||
// Looks up by z_address, so if one is found here and not have last pointers equal to this one,
|
||||
// there is another one.
|
||||
VirtualFramebuffer *prevDepth = GetLatestDepthBufferAt(vfb->z_address, vfb->z_stride);
|
||||
|
||||
// We might already want to copy depth, in case this is a temp buffer. See #7810.
|
||||
if (prevDepth != vfb) {
|
||||
if (!params.isClearingDepth && prevDepth) {
|
||||
BlitFramebufferDepth(prevDepth, vfb);
|
||||
}
|
||||
}
|
||||
|
||||
SetColorUpdated(vfb, skipDrawReason);
|
||||
|
||||
INFO_LOG(FRAMEBUF, "Creating FBO for %08x (z: %08x) : %d x %d x %s", vfb->fb_address, vfb->z_address, vfb->width, vfb->height, GeBufferFormatToString(vfb->format));
|
||||
@@ -510,18 +506,19 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
VirtualFramebuffer *prev = currentRenderVfb_;
|
||||
currentRenderVfb_ = vfb;
|
||||
NotifyRenderFramebufferSwitched(prev, vfb, params.isClearingDepth);
|
||||
gstate_c.usingDepth = false; // reset depth buffer tracking
|
||||
} else {
|
||||
// Something changed, but we still got the same framebuffer we were already rendering to.
|
||||
// Might not be a lot to do here, we check in NotifyRenderFramebufferUpdated
|
||||
vfb->last_frame_render = gpuStats.numFlips;
|
||||
frameLastFramebufUsed_ = gpuStats.numFlips;
|
||||
vfb->dirtyAfterDisplay = true;
|
||||
if ((skipDrawReason & SKIPDRAW_SKIPFRAME) == 0)
|
||||
vfb->reallyDirtyAfterDisplay = true;
|
||||
|
||||
NotifyRenderFramebufferUpdated(vfb, vfbFormatChanged);
|
||||
}
|
||||
|
||||
vfb->colorBindSeq = GetBindSeqCount();
|
||||
vfb->depthBindSeq = GetBindSeqCount();
|
||||
|
||||
gstate_c.curRTWidth = vfb->width;
|
||||
gstate_c.curRTHeight = vfb->height;
|
||||
@@ -530,6 +527,26 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
|
||||
return vfb;
|
||||
}
|
||||
|
||||
// Called on the first use of depth in a render pass.
|
||||
void FramebufferManagerCommon::SetDepthFrameBuffer() {
|
||||
if (!currentRenderVfb_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Looks up by z_address, so if one is found here and not have last pointers equal to this one,
|
||||
// there is another one.
|
||||
VirtualFramebuffer *prevDepth = GetLatestDepthBufferAt(currentRenderVfb_->z_address, currentRenderVfb_->z_stride);
|
||||
|
||||
if (prevDepth != currentRenderVfb_) {
|
||||
if (!gstate_c.clearingDepth && prevDepth) {
|
||||
BlitFramebufferDepth(prevDepth, currentRenderVfb_);
|
||||
}
|
||||
prevDepth = currentRenderVfb_;
|
||||
}
|
||||
|
||||
currentRenderVfb_->depthBindSeq = GetBindSeqCount();
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) {
|
||||
// Notify the texture cache of both the color and depth buffers.
|
||||
textureCache_->NotifyFramebuffer(v, NOTIFY_FB_DESTROYED);
|
||||
@@ -669,17 +686,6 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
|
||||
textureCache_->ForgetLastTexture();
|
||||
shaderManager_->DirtyLastShader();
|
||||
|
||||
// Copy depth between the framebuffers, if the z_address is the same (checked inside.)
|
||||
VirtualFramebuffer * prevDepth = GetLatestDepthBufferAt(vfb->z_address, vfb->z_stride);
|
||||
|
||||
// We might already want to copy depth, in case this is a temp buffer. See #7810.
|
||||
if (prevDepth != vfb) {
|
||||
if (!isClearingDepth && prevDepth) {
|
||||
BlitFramebufferDepth(prevDepth, vfb);
|
||||
}
|
||||
prevDepth = vfb;
|
||||
}
|
||||
|
||||
if (vfb->drawnFormat != vfb->format) {
|
||||
ReinterpretFramebuffer(vfb, vfb->drawnFormat, vfb->format);
|
||||
}
|
||||
|
||||
@@ -266,6 +266,8 @@ public:
|
||||
return vfb;
|
||||
}
|
||||
}
|
||||
void SetDepthFrameBuffer();
|
||||
|
||||
void RebindFramebuffer(const char *tag);
|
||||
std::vector<FramebufferInfo> GetFramebufferList() const;
|
||||
|
||||
|
||||
@@ -1685,6 +1685,16 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gstate_c.usingDepth) {
|
||||
bool isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask();;
|
||||
|
||||
if ((gstate.isDepthTestEnabled() || isClearingDepth)) {
|
||||
gstate_c.usingDepth = true;
|
||||
gstate_c.clearingDepth = isClearingDepth;
|
||||
framebufferManager_->SetDepthFrameBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
const void *verts = Memory::GetPointerUnchecked(gstate_c.vertexAddr);
|
||||
const void *inds = nullptr;
|
||||
u32 vertexType = gstate.vertType;
|
||||
|
||||
@@ -572,6 +572,9 @@ struct GPUStateCache {
|
||||
|
||||
uint64_t dirty;
|
||||
|
||||
bool usingDepth; // For deferred depth copies.
|
||||
bool clearingDepth;
|
||||
|
||||
bool textureFullAlpha;
|
||||
bool vertexFullAlpha;
|
||||
|
||||
|
||||
Reference in new issue
Block a user