Use sequence numbers instead of a tracking array for depth buffers

This commit is contained in:
Henrik Rydgård 2022-08-17 10:34:07 +02:00
parent 9498ff17f6
commit 74f1c94ddb
2 changed files with 22 additions and 81 deletions

View file

@ -71,12 +71,6 @@ FramebufferManagerCommon::~FramebufferManagerCommon() {
} }
bvfbs_.clear(); bvfbs_.clear();
// Shouldn't be anything left here in theory, but just in case...
for (auto trackedDepth : trackedDepthBuffers_) {
delete trackedDepth;
}
trackedDepthBuffers_.clear();
delete presentation_; delete presentation_;
} }
@ -375,17 +369,11 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
// Lookup in the depth tracking to find which VFB has the latest version of this Z buffer. // Lookup in the depth tracking to find which VFB has the latest version of this Z buffer.
// Then bind it in color-to-depth mode. // Then bind it in color-to-depth mode.
// //
// We are going to do this by having a special render mode where we take color and move to // We do this by having a special render mode where we take color and move to
// depth in the fragment shader, and set color writes to off. // depth in the fragment shader, and set color writes to off.
// //
// We'll need a special fragment shader flag to convert color to depth. // We use a special fragment shader flag to convert color to depth.
vfb = GetLatestDepthBufferAt(params.fb_address /* !!! */, params.fb_stride);
for (auto &depth : this->trackedDepthBuffers_) {
if (depth->z_address == params.fb_address && depth->z_stride == params.fb_stride) {
// Found the matching depth buffer. Use this vfb.
vfb = depth->vfb;
}
}
} }
gstate_c.SetFramebufferRenderMode(mode); gstate_c.SetFramebufferRenderMode(mode);
@ -453,14 +441,13 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
// Looks up by z_address, so if one is found here and not have last pointers equal to this one, // Looks up by z_address, so if one is found here and not have last pointers equal to this one,
// there is another one. // there is another one.
TrackedDepthBuffer *prevDepth = GetOrCreateTrackedDepthBuffer(vfb); 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. // We might already want to copy depth, in case this is a temp buffer. See #7810.
if (prevDepth->vfb != vfb) { if (prevDepth != vfb) {
if (!params.isClearingDepth && prevDepth->vfb) { if (!params.isClearingDepth && prevDepth) {
BlitFramebufferDepth(prevDepth->vfb, vfb); BlitFramebufferDepth(prevDepth, vfb);
} }
prevDepth->vfb = vfb;
} }
SetColorUpdated(vfb, skipDrawReason); SetColorUpdated(vfb, skipDrawReason);
@ -558,13 +545,6 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) {
if (prevPrevDisplayFramebuf_ == v) if (prevPrevDisplayFramebuf_ == v)
prevPrevDisplayFramebuf_ = nullptr; prevPrevDisplayFramebuf_ = nullptr;
// Remove any depth buffer tracking related to this vfb.
for (auto it = trackedDepthBuffers_.begin(); it != trackedDepthBuffers_.end(); it++) {
if ((*it)->vfb == v) {
(*it)->vfb = nullptr; // Mark for deletion in the next Decimate
}
}
delete v; delete v;
} }
@ -626,32 +606,16 @@ void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, Vir
dst->last_frame_depth_updated = gpuStats.numFlips; dst->last_frame_depth_updated = gpuStats.numFlips;
} }
TrackedDepthBuffer *FramebufferManagerCommon::GetOrCreateTrackedDepthBuffer(VirtualFramebuffer *vfb) { VirtualFramebuffer *FramebufferManagerCommon::GetLatestDepthBufferAt(u32 z_address, u16 z_stride) {
for (auto tracked : trackedDepthBuffers_) { int maxSeq = -1;
// Disable tracking if color of the new vfb is clashing with tracked depth. VirtualFramebuffer *latestDepth = nullptr;
if (vfb->fb_address == tracked->z_address) { for (auto vfb : vfbs_) {
tracked->vfb = nullptr; // this is checked for. Cheaper than deleting. if (vfb->z_address == z_address && vfb->z_stride == z_stride && vfb->depthBindSeq > maxSeq) {
continue; maxSeq = vfb->depthBindSeq;
} latestDepth = vfb;
if (vfb->z_address == tracked->z_address) {
if (vfb->z_stride == tracked->z_stride) {
return tracked;
} else {
// Stride has changed, mark as bad.
tracked->vfb = nullptr;
} }
} }
} return latestDepth;
TrackedDepthBuffer *tracked = new TrackedDepthBuffer();
tracked->vfb = vfb;
tracked->z_address = vfb->z_address;
tracked->z_stride = vfb->z_stride;
trackedDepthBuffers_.push_back(tracked);
return tracked;
} }
void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) { void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) {
@ -703,14 +667,14 @@ void FramebufferManagerCommon::NotifyRenderFramebufferSwitched(VirtualFramebuffe
shaderManager_->DirtyLastShader(); shaderManager_->DirtyLastShader();
// Copy depth between the framebuffers, if the z_address is the same (checked inside.) // Copy depth between the framebuffers, if the z_address is the same (checked inside.)
TrackedDepthBuffer *prevDepth = GetOrCreateTrackedDepthBuffer(vfb); 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. // We might already want to copy depth, in case this is a temp buffer. See #7810.
if (prevDepth->vfb != vfb) { if (prevDepth != vfb) {
if (!isClearingDepth && prevDepth->vfb) { if (!isClearingDepth && prevDepth) {
BlitFramebufferDepth(prevDepth->vfb, vfb); BlitFramebufferDepth(prevDepth, vfb);
} }
prevDepth->vfb = vfb; prevDepth = vfb;
} }
if (vfb->drawnFormat != vfb->format) { if (vfb->drawnFormat != vfb->format) {
@ -1234,16 +1198,6 @@ void FramebufferManagerCommon::DecimateFBOs() {
bvfbs_.erase(bvfbs_.begin() + i--); bvfbs_.erase(bvfbs_.begin() + i--);
} }
} }
// Also clean up the TrackedDepthBuffer array...
for (auto it = trackedDepthBuffers_.begin(); it != trackedDepthBuffers_.end();) {
if ((*it)->vfb == nullptr) {
delete *it;
it = trackedDepthBuffers_.erase(it);
} else {
it++;
}
}
} }
// Requires width/height to be set already. // Requires width/height to be set already.
@ -2220,6 +2174,7 @@ void FramebufferManagerCommon::ReadFramebufferToMemory(VirtualFramebuffer *vfb,
// We'll pseudo-blit framebuffers here to get a resized version of vfb. // We'll pseudo-blit framebuffers here to get a resized version of vfb.
if (gameUsesSequentialCopies_) { if (gameUsesSequentialCopies_) {
// Ignore the x/y/etc., read the entire thing. // Ignore the x/y/etc., read the entire thing.
// TODO: What game did we need this for?
x = 0; x = 0;
y = 0; y = 0;
w = vfb->width; w = vfb->width;

View file

@ -147,18 +147,6 @@ struct VirtualFramebuffer {
int last_frame_depth_render; int last_frame_depth_render;
}; };
struct TrackedDepthBuffer {
u32 z_address;
int z_stride;
// Really need to make sure we're killing these TrackedDepthBuffer's off when the VirtualFrameBuffers die.
VirtualFramebuffer *vfb;
// Could do full tracking of which framebuffers are used with this depth buffer,
// but probably not necessary.
// std::set<std::pair<u32, u32>> seen_fbs;
};
struct FramebufferHeuristicParams { struct FramebufferHeuristicParams {
u32 fb_address; u32 fb_address;
u32 z_address; u32 z_address;
@ -300,7 +288,7 @@ public:
void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes);
void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride); void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride);
TrackedDepthBuffer *GetOrCreateTrackedDepthBuffer(VirtualFramebuffer *vfb); VirtualFramebuffer *GetLatestDepthBufferAt(u32 z_address, u16 z_stride);
void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height); void DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height);
@ -481,8 +469,6 @@ protected:
std::vector<VirtualFramebuffer *> vfbs_; std::vector<VirtualFramebuffer *> vfbs_;
std::vector<VirtualFramebuffer *> bvfbs_; // blitting framebuffers (for download) std::vector<VirtualFramebuffer *> bvfbs_; // blitting framebuffers (for download)
std::vector<TrackedDepthBuffer *> trackedDepthBuffers_;
bool gameUsesSequentialCopies_ = false; bool gameUsesSequentialCopies_ = false;
// Sampled in BeginFrame/UpdateSize for safety. // Sampled in BeginFrame/UpdateSize for safety.