mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-09-10 17:58:50 +02:00
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();
|
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)
|
if (srcTexture == null)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +83,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
dstCopyTextureFormat = dstCopyTexture.Format.Convert();
|
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)
|
if (dstTexture == null)
|
||||||
{
|
{
|
||||||
|
@ -90,30 +109,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
|
|
||||||
srcTexture.HostTexture.CopyTo(dstTexture.HostTexture, srcRegion, dstRegion, linearFilter);
|
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();
|
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.
|
/// Tries to find an existing texture, or create a new one if not found.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="copyTexture">Copy texture to find or create</param>
|
/// <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="formatInfo">Format information of the copy texture</param>
|
||||||
/// <param name="preferScaling">Indicates if the texture should be scaled from the start</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>
|
/// <param name="sizeHint">A hint indicating the minimum used size for the texture</param>
|
||||||
/// <returns>The texture</returns>
|
/// <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 gobBlocksInY = copyTexture.MemoryLayout.UnpackGobBlocksInY();
|
||||||
int gobBlocksInZ = copyTexture.MemoryLayout.UnpackGobBlocksInZ();
|
int gobBlocksInZ = copyTexture.MemoryLayout.UnpackGobBlocksInZ();
|
||||||
|
@ -497,7 +498,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureInfo info = new TextureInfo(
|
TextureInfo info = new TextureInfo(
|
||||||
copyTexture.Address.Pack(),
|
copyTexture.Address.Pack() + offset,
|
||||||
width,
|
width,
|
||||||
copyTexture.Height,
|
copyTexture.Height,
|
||||||
copyTexture.Depth,
|
copyTexture.Depth,
|
||||||
|
|
Loading…
Reference in a new issue