Merge pull request #21324 from hrydgard/silent-hill-shadows

WIP: Apply changes by fcrwr, fixing (mostly) shadows in Silent Hill: Shattered memories
This commit is contained in:
Henrik Rydgård
2026-03-18 09:06:55 +01:00
committed by GitHub
2 changed files with 55 additions and 2 deletions
+44
View File
@@ -2701,6 +2701,16 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
return true; // Skip the memory copy.
}
// If the formats mismatch badly, we need a resolve.
if (srcRect.vfb && dstRect.vfb && srcRect.channel == RASTER_COLOR && dstRect.channel == RASTER_COLOR && srcRect.vfb->fb_format != dstRect.vfb->fb_format) {
WARN_LOG_N_TIMES(dstnotsrc, 5, Log::G3D, "Mismatched color format requiring reinterpret during block transfer %dx%d %dbpp from %08x (x:%d y:%d stride:%d %s) -> %08x (x:%d y:%d stride:%d %s)",
width, height, bpp,
srcBasePtr, srcRect.x_bytes / bpp, srcRect.y, srcStride, GeBufferFormatToString(srcRect.vfb->fb_format),
dstBasePtr, dstRect.x_bytes / bpp, dstRect.y, dstStride, GeBufferFormatToString(dstRect.vfb->fb_format));
// Seen in Silent Hill: Shattered Memories.
srcRect.vfb = ResolveFramebufferColorToFormat(srcRect.vfb, dstRect.vfb->fb_format);
}
// Straightforward blit between two same-format framebuffers.
if (srcRect.vfb && srcRect.channel == dstRect.channel && srcRect.vfb->Format(srcRect.channel) == dstRect.vfb->Format(dstRect.channel)) {
WARN_LOG_N_TIMES(dstnotsrc, 5, Log::G3D, "Inter-buffer %s block transfer %dx%d %dbpp from %08x (x:%d y:%d stride:%d %s) -> %08x (x:%d y:%d stride:%d %s)",
@@ -2728,6 +2738,40 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
WARN_LOG_N_TIMES(blockformat, 5, Log::G3D, "Mismatched buffer formats in block transfer: %s->%s (%dx%d)",
GeBufferFormatToString(srcRect.vfb->Format(srcRect.channel)), GeBufferFormatToString(dstRect.vfb->Format(dstRect.channel)),
width, height);
VirtualFramebuffer *src = srcRect.vfb, *dst = dstRect.vfb;
float scaleFactorX = 1.0f;
Draw2DPipeline *pipeline = GetReinterpretPipeline(src->fb_format, dst->fb_format, &scaleFactorX);
if (pipeline) {
const char *pass_name = reinterpretStrings[(int)src->fb_format][(int)dst->fb_format];
int srcWidth = width * src->renderScaleFactor;
int srcHeight = height * src->renderScaleFactor;
int dstWidth = width * dst->renderScaleFactor;
int dstHeight = height * dst->renderScaleFactor;
int srcX1 = srcX * src->renderScaleFactor;
int srcY1 = srcY * src->renderScaleFactor;
int srcX2 = srcX1 + srcWidth;
int srcY2 = srcY1 + srcHeight;
int dstX1 = dstX * dst->renderScaleFactor;
int dstY1 = dstY * dst->renderScaleFactor;
int dstX2 = dstX1 + dstWidth;
int dstY2 = dstY1 + dstHeight;
srcX1 /= scaleFactorX;
srcX2 /= scaleFactorX;
gpuStats.numReinterpretCopies++;
FlushBeforeCopy();
BlitUsingRaster(src->fbo, srcX1, srcY1, srcX2, srcY2,
dst->fbo, dstX1, dstY1, dstX2, dstY2, false, dst->renderScaleFactor, pipeline, pass_name);
RebindFramebuffer("RebindFramebuffer - Inter-buffer block transfer with mismatched formats");
SetColorUpdated(dst, skipDrawReason);
return true;
}
}
// TODO