Use sequence numbers instead of a tracking array for depth buffers
This commit is contained in:
parent
9498ff17f6
commit
74f1c94ddb
2 changed files with 22 additions and 81 deletions
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue