diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2021-06-02 20:30:48 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-03 01:30:48 +0200 |
| commit | b84ba434066ad47389134efac80d2279a10e75ac (patch) | |
| tree | bfc5474b08065ddb04d9fa66b5907bfd2fe73f80 | |
| parent | 534a45d6e822b4d2694420d80bc6537204a6a1e2 (diff) | |
Fix texture blit off-by-one errors (#2335)
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs | 26 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/State/CopyTextureControl.cs | 5 |
2 files changed, 27 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs index 1a22bdbf..da08f31a 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs @@ -24,11 +24,29 @@ namespace Ryujinx.Graphics.Gpu.Engine var control = state.Get<CopyTextureControl>(MethodOffset.CopyTextureControl); - int srcX1 = (int)(region.SrcXF >> 32); - int srcY1 = (int)(region.SrcYF >> 32); + bool originCorner = control.UnpackOriginCorner(); - int srcX2 = (int)((region.SrcXF + region.SrcWidthRF * region.DstWidth) >> 32); - int srcY2 = (int)((region.SrcYF + region.SrcHeightRF * region.DstHeight) >> 32); + long srcX = region.SrcXF; + long srcY = region.SrcYF; + + if (originCorner) + { + // If the origin is corner, it is assumed that the guest API + // is manually centering the origin by adding a offset to the + // source region X/Y coordinates. + // Here we attempt to remove such offset to ensure we have the correct region. + // The offset is calculated as FactorXY / 2.0, where FactorXY = SrcXY / DstXY, + // so we do the same here by dividing the fixed point value by 2, while + // throwing away the fractional part to avoid rounding errors. + srcX -= (region.SrcWidthRF >> 33) << 32; + srcY -= (region.SrcHeightRF >> 33) << 32; + } + + int srcX1 = (int)(srcX >> 32); + int srcY1 = (int)(srcY >> 32); + + int srcX2 = srcX1 + (int)((region.SrcWidthRF * region.DstWidth + uint.MaxValue) >> 32); + int srcY2 = srcY1 + (int)((region.SrcHeightRF * region.DstHeight + uint.MaxValue) >> 32); int dstX1 = region.DstX; int dstY1 = region.DstY; diff --git a/Ryujinx.Graphics.Gpu/State/CopyTextureControl.cs b/Ryujinx.Graphics.Gpu/State/CopyTextureControl.cs index 50fb9010..d6256f68 100644 --- a/Ryujinx.Graphics.Gpu/State/CopyTextureControl.cs +++ b/Ryujinx.Graphics.Gpu/State/CopyTextureControl.cs @@ -9,6 +9,11 @@ namespace Ryujinx.Graphics.Gpu.State public uint Packed; #pragma warning restore CS0649 + public bool UnpackOriginCorner() + { + return (Packed & 1u) != 0; + } + public bool UnpackLinearFilter() { return (Packed & (1u << 4)) != 0; |
