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 /Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs | |
parent | 534a45d6e822b4d2694420d80bc6537204a6a1e2 (diff) |
Fix texture blit off-by-one errors (#2335)
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MethodCopyTexture.cs | 26 |
1 files changed, 22 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; |