Use a different method for out of bounds blit (#2302)
* Use a different method for out of bounds blit * This is not needed
This commit is contained in:
parent
a03bbef4d6
commit
e9c15d32cb
2 changed files with 24 additions and 28 deletions
|
@ -43,7 +43,26 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
var srcCopyTextureFormat = srcCopyTexture.Format.Convert();
|
||||
|
||||
Texture srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat, true, srcHint);
|
||||
int srcWidthAligned = srcCopyTexture.Stride / srcCopyTextureFormat.BytesPerPixel;
|
||||
|
||||
ulong offset = 0;
|
||||
|
||||
// For an out of bounds copy, we must ensure that the copy wraps to the next line,
|
||||
// so for a copy from a 64x64 texture, in the region [32, 96[, there are 32 pixels that are
|
||||
// outside the bounds of the texture. We fill the destination with the first 32 pixels
|
||||
// of the next line on the source texture.
|
||||
// This can be done by simply adding an offset to the texture address, so that the initial
|
||||
// gap is skipped and the copy is inside bounds again.
|
||||
// This is required by the proprietary guest OpenGL driver.
|
||||
if (srcCopyTexture.LinearLayout && srcCopyTexture.Width == srcX2 && srcX2 > srcWidthAligned && srcX1 > 0)
|
||||
{
|
||||
offset = (ulong)(srcX1 * srcCopyTextureFormat.BytesPerPixel);
|
||||
srcCopyTexture.Width -= srcX1;
|
||||
srcX2 -= srcX1;
|
||||
srcX1 = 0;
|
||||
}
|
||||
|
||||
Texture srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, offset, srcCopyTextureFormat, true, srcHint);
|
||||
|
||||
if (srcTexture == null)
|
||||
{
|
||||
|
@ -64,7 +83,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
dstCopyTextureFormat = dstCopyTexture.Format.Convert();
|
||||
}
|
||||
|
||||
Texture dstTexture = TextureManager.FindOrCreateTexture(dstCopyTexture, dstCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled, dstHint);
|
||||
Texture dstTexture = TextureManager.FindOrCreateTexture(dstCopyTexture, 0, dstCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled, dstHint);
|
||||
|
||||
if (dstTexture == null)
|
||||
{
|
||||
|
@ -90,30 +109,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
|||
|
||||
srcTexture.HostTexture.CopyTo(dstTexture.HostTexture, srcRegion, dstRegion, linearFilter);
|
||||
|
||||
// For an out of bounds copy, we must ensure that the copy wraps to the next line,
|
||||
// so for a copy from a 64x64 texture, in the region [32, 96[, there are 32 pixels that are
|
||||
// outside the bounds of the texture. We fill the destination with the first 32 pixels
|
||||
// of the next line on the source texture.
|
||||
// This can be emulated with 2 copies (the first copy handles the region inside the bounds,
|
||||
// the second handles the region outside of the bounds).
|
||||
// We must also extend the source texture by one line to ensure we can wrap on the last line.
|
||||
// This is required by the (guest) OpenGL driver.
|
||||
if (srcX2 / srcTexture.Info.SamplesInX > srcTexture.Info.Width)
|
||||
{
|
||||
srcCopyTexture.Height++;
|
||||
|
||||
srcTexture = TextureManager.FindOrCreateTexture(srcCopyTexture, srcCopyTextureFormat, srcTexture.ScaleMode == TextureScaleMode.Scaled, srcHint);
|
||||
scale = srcTexture.ScaleFactor;
|
||||
|
||||
srcRegion = new Extents2D(
|
||||
(int)Math.Ceiling(scale * ((srcX1 / srcTexture.Info.SamplesInX) - srcTexture.Info.Width)),
|
||||
(int)Math.Ceiling(scale * ((srcY1 / srcTexture.Info.SamplesInY) + 1)),
|
||||
(int)Math.Ceiling(scale * ((srcX2 / srcTexture.Info.SamplesInX) - srcTexture.Info.Width)),
|
||||
(int)Math.Ceiling(scale * ((srcY2 / srcTexture.Info.SamplesInY) + 1)));
|
||||
|
||||
srcTexture.HostTexture.CopyTo(dstTexture.HostTexture, srcRegion, dstRegion, linearFilter);
|
||||
}
|
||||
|
||||
dstTexture.SignalModified();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -476,11 +476,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// Tries to find an existing texture, or create a new one if not found.
|
||||
/// </summary>
|
||||
/// <param name="copyTexture">Copy texture to find or create</param>
|
||||
/// <param name="offset">Offset to be added to the physical texture address</param>
|
||||
/// <param name="formatInfo">Format information of the copy texture</param>
|
||||
/// <param name="preferScaling">Indicates if the texture should be scaled from the start</param>
|
||||
/// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
||||
/// <returns>The texture</returns>
|
||||
public Texture FindOrCreateTexture(CopyTexture copyTexture, FormatInfo formatInfo, bool preferScaling = true, Size? sizeHint = null)
|
||||
public Texture FindOrCreateTexture(CopyTexture copyTexture, ulong offset, FormatInfo formatInfo, bool preferScaling = true, Size? sizeHint = null)
|
||||
{
|
||||
int gobBlocksInY = copyTexture.MemoryLayout.UnpackGobBlocksInY();
|
||||
int gobBlocksInZ = copyTexture.MemoryLayout.UnpackGobBlocksInZ();
|
||||
|
@ -497,7 +498,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
}
|
||||
|
||||
TextureInfo info = new TextureInfo(
|
||||
copyTexture.Address.Pack(),
|
||||
copyTexture.Address.Pack() + offset,
|
||||
width,
|
||||
copyTexture.Height,
|
||||
copyTexture.Depth,
|
||||
|
|
Reference in a new issue