Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy color to depth, defer depth buffer copies #15858

Merged
merged 7 commits into from
Aug 20, 2022
10 changes: 4 additions & 6 deletions GPU/Common/Draw2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,8 @@ RasterChannel GenerateDraw2D565ToDepthFs(ShaderWriter &writer) {
// have to apply the scaling.
DepthScaleFactors factors = GetDepthScaleFactors();
writer.C(" vec3 rgb = ").SampleTexture2D("tex", "v_texcoord.xy").C(".xyz;\n");
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0) / 65535.0; \n");
if (factors.scale != 1.0 || factors.offset != 0.0) {
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.scale / 65535.0f, factors.offset);
} else {
writer.C(" gl_FragDepth = depthValue;\n");
}
writer.F(" highp float depthValue = (floor(rgb.x * 31.99) + floor(rgb.y * 63.99) * 32.0 + floor(rgb.z * 31.99) * 2048.0); \n");
writer.F(" gl_FragDepth = (depthValue / %f) + %f;\n", factors.scale, factors.offset);
writer.EndFSMain("outColor", FSFLAG_WRITEDEPTH);
return RASTER_DEPTH;
}
Expand Down Expand Up @@ -200,6 +196,7 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver
}
if (!draw2DPipelineDepth_) {
draw2DPipelineDepth_ = Create2DPipeline(&GenerateDraw2DDepthFs);
linearFilter = false;
}
draw_->BindPipeline(draw2DPipelineDepth_);
break;
Expand All @@ -211,6 +208,7 @@ void FramebufferManagerCommon::DrawStrip2D(Draw::Texture *tex, Draw2DVertex *ver
}
if (!draw2DPipeline565ToDepth_) {
draw2DPipeline565ToDepth_ = Create2DPipeline(&GenerateDraw2D565ToDepthFs);
linearFilter = false;
}
draw_->BindPipeline(draw2DPipeline565ToDepth_);
break;
Expand Down
18 changes: 10 additions & 8 deletions GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
vfb->lastFrameNewSize = gpuStats.numFlips;
vfb->format = params.fmt;
vfb->drawnFormat = params.fmt;
vfb->usageFlags = FB_USAGE_RENDERTARGET;
vfb->usageFlags = FB_USAGE_RENDER_COLOR;

u32 byteSize = ColorBufferByteSize(vfb);
if (Memory::IsVRAMAddress(params.fb_address) && params.fb_address + byteSize > framebufRangeEnd_) {
Expand Down Expand Up @@ -454,7 +454,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
} else if (vfbs_[i]->z_stride != 0 && params.z_address == vfbs_[i]->z_address && params.fb_address != vfbs_[i]->fb_address && !sharingReported) {
// This happens a lot, but virtually always it's cleared.
// It's possible the other might not clear, but when every game is reported it's not useful.
if (params.isWritingDepth) {
if (params.isWritingDepth && (vfbs_[i]->usageFlags & FB_USAGE_RENDER_DEPTH)) {
WARN_LOG(SCEGE, "FBO reusing depthbuffer, c=%08x/d=%08x and c=%08x/d=%08x", params.fb_address, params.z_address, vfbs_[i]->fb_address, vfbs_[i]->z_address);
sharingReported = true;
}
Expand All @@ -465,7 +465,7 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame
} else if (vfb != currentRenderVfb_) {
// Use it as a render target.
DEBUG_LOG(FRAMEBUF, "Switching render target to FBO for %08x: %d x %d x %d ", vfb->fb_address, vfb->width, vfb->height, vfb->format);
vfb->usageFlags |= FB_USAGE_RENDERTARGET;
vfb->usageFlags |= FB_USAGE_RENDER_COLOR;
vfb->last_frame_render = gpuStats.numFlips;
frameLastFramebufUsed_ = gpuStats.numFlips;
vfb->dirtyAfterDisplay = true;
Expand Down Expand Up @@ -505,6 +505,7 @@ void FramebufferManagerCommon::SetDepthFrameBuffer() {
// "Resolve" the depth buffer, by copying from any overlapping buffers with fresher content.
CopyToDepthFromOverlappingFramebuffers(currentRenderVfb_);

currentRenderVfb_->usageFlags |= FB_USAGE_RENDER_DEPTH;
currentRenderVfb_->depthBindSeq = GetBindSeqCount();
}

Expand All @@ -523,16 +524,17 @@ void FramebufferManagerCommon::CopyToDepthFromOverlappingFramebuffers(VirtualFra
};

std::vector<CopySource> sources;
for (auto src: vfbs_) {
for (auto src : vfbs_) {
if (src == dest)
continue;

if (src->fb_address == dest->z_address && src->fb_stride == dest->z_stride && src->format == GE_FORMAT_565) {
if (src->colorBindSeq < dest->depthBindSeq) {
if (src->colorBindSeq > dest->depthBindSeq) {
// Source has newer data than the current buffer, use it.
sources.push_back(CopySource{ src, RASTER_COLOR });
}
} else if (src->z_address == dest->z_address && src->z_stride == dest->z_stride && src->depthBindSeq > dest->depthBindSeq) {
// Don't bother if the buffer was from another frame. This heuristic is old.
hrydgard marked this conversation as resolved.
Show resolved Hide resolved
sources.push_back(CopySource{ src, RASTER_DEPTH });
} else {
// TODO: Do more detailed overlap checks here.
Expand Down Expand Up @@ -1572,7 +1574,7 @@ VirtualFramebuffer *FramebufferManagerCommon::CreateRAMFramebuffer(uint32_t fbAd
vfb->bufferHeight = vfb->height;
vfb->format = format;
vfb->drawnFormat = GE_FORMAT_8888;
vfb->usageFlags = FB_USAGE_RENDERTARGET;
vfb->usageFlags = FB_USAGE_RENDER_COLOR;
SetColorUpdated(vfb, 0);
char name[64];
snprintf(name, sizeof(name), "%08x_color_RAM", vfb->fb_address);
Expand Down Expand Up @@ -1640,7 +1642,7 @@ VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFram
UpdateDownloadTempBuffer(nvfb);
}

nvfb->usageFlags |= FB_USAGE_RENDERTARGET;
nvfb->usageFlags |= FB_USAGE_RENDER_COLOR;
nvfb->last_frame_render = gpuStats.numFlips;
nvfb->dirtyAfterDisplay = true;

Expand Down Expand Up @@ -1957,7 +1959,7 @@ void FramebufferManagerCommon::UpdateFramebufUsage(VirtualFramebuffer *vfb) {

checkFlag(FB_USAGE_DISPLAYED_FRAMEBUFFER, vfb->last_frame_displayed);
checkFlag(FB_USAGE_TEXTURE, vfb->last_frame_used);
checkFlag(FB_USAGE_RENDERTARGET, vfb->last_frame_render);
checkFlag(FB_USAGE_RENDER_COLOR, vfb->last_frame_render);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm, what if it's only rendering depth? I could see it being useful to know that... hm. Maybe for render-to-texture selection too. Can't remember if I've seen games render a scene with RGB and stencil all masked out, just to establish depth... feel like I have...

-[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.

Yeah, this tracking isn't perfect yet. I don't think I have seen such a case though, but I also don't think it'll hurt very much if we get that wrong..

checkFlag(FB_USAGE_CLUT, vfb->last_frame_clut);
}

Expand Down
3 changes: 2 additions & 1 deletion GPU/Common/FramebufferManagerCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@

enum {
FB_USAGE_DISPLAYED_FRAMEBUFFER = 1,
FB_USAGE_RENDERTARGET = 2,
FB_USAGE_RENDER_COLOR = 2,
FB_USAGE_TEXTURE = 4,
FB_USAGE_CLUT = 8,
FB_USAGE_DOWNLOAD = 16,
FB_USAGE_DOWNLOAD_CLEAR = 32,
FB_USAGE_BLUE_TO_ALPHA = 64,
FB_USAGE_FIRST_FRAME_SAVED = 128,
FB_USAGE_RENDER_DEPTH = 256,
};

enum {
Expand Down
8 changes: 1 addition & 7 deletions GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,7 @@ inline int dimHeight(u16 dim) {
// Vulkan color formats:
// TODO
TextureCacheCommon::TextureCacheCommon(Draw::DrawContext *draw)
: draw_(draw),
clutLastFormat_(0xFFFFFFFF),
clutTotalBytes_(0),
clutMaxBytes_(0),
clutRenderAddress_(0xFFFFFFFF),
clutAlphaLinear_(false),
isBgraBackend_(false) {
: draw_(draw) {
decimationCounter_ = TEXCACHE_DECIMATION_INTERVAL;

// TODO: Clamp down to 256/1KB? Need to check mipmapShareClut and clamp loadclut.
Expand Down
12 changes: 6 additions & 6 deletions GPU/Common/TextureCacheCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,13 +444,13 @@ class TextureCacheCommon {
u32 *clutBufConverted_;
// This is the active one.
u32 *clutBuf_;
u32 clutLastFormat_;
u32 clutTotalBytes_;
u32 clutMaxBytes_;
u32 clutRenderAddress_;
u32 clutLastFormat_ = 0xFFFFFFFF;
u32 clutTotalBytes_ = 0;
u32 clutMaxBytes_ = 0;
u32 clutRenderAddress_ = 0xFFFFFFFF;
u32 clutRenderOffset_;
// True if the clut is just alpha values in the same order (RGBA4444-bit only.)
bool clutAlphaLinear_;
bool clutAlphaLinear_ = false;
u16 clutAlphaLinearColor_;

int standardScaleFactor_;
Expand All @@ -461,7 +461,7 @@ class TextureCacheCommon {
bool nextNeedsChange_;
bool nextNeedsRebuild_;

bool isBgraBackend_;
bool isBgraBackend_ = false;

u32 expandClut_[256];
};
Expand Down