Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 30 additions & 24 deletions GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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));
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions GPU/Common/FramebufferManagerCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ class FramebufferManagerCommon {
return vfb;
}
}
void SetDepthFrameBuffer();

void RebindFramebuffer(const char *tag);
std::vector<FramebufferInfo> GetFramebufferList() const;

Expand Down
10 changes: 10 additions & 0 deletions GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,16 @@ void GPUCommon::Execute_Prim(u32 op, u32 diff) {
return;
}

if (!gstate_c.usingDepth) {
bool isClearingDepth = gstate.isModeClear() && gstate.isClearModeDepthMask();;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ;;.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was later removed.


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;
Expand Down
3 changes: 3 additions & 0 deletions GPU/GPUState.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,9 @@ struct GPUStateCache {

uint64_t dirty;

bool usingDepth; // For deferred depth copies.
bool clearingDepth;

bool textureFullAlpha;
bool vertexFullAlpha;

Expand Down