Improve linear texture compatibility rules (#2099)
* Improve linear texture compatibility rules Fixes an issue where small or width-aligned (rather than byte aligned) textures would fail to create a view of existing data. Creates a copy dependency as size change may be risky. * Minor cleanup * Remove Size Change for Copy Depenedencies The copy to the target (potentially different sized) texture can properly deal with cropping by itself. * Move StrideAlignment and GobAlignment into Constants
This commit is contained in:
parent
39899c0407
commit
9b7335a63b
5 changed files with 29 additions and 15 deletions
|
@ -69,5 +69,15 @@ namespace Ryujinx.Graphics.Gpu
|
||||||
/// Maximum size of gl_ClipDistance array in shaders.
|
/// Maximum size of gl_ClipDistance array in shaders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int TotalClipDistances = 8;
|
public const int TotalClipDistances = 8;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Byte alignment for texture stride.
|
||||||
|
/// </summary>
|
||||||
|
public const int StrideAlignment = 32;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Byte alignment for block linear textures
|
||||||
|
/// </summary>
|
||||||
|
public const int GobAlignment = 64;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,9 +8,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
partial class Methods
|
partial class Methods
|
||||||
{
|
{
|
||||||
private const int StrideAlignment = 32;
|
|
||||||
private const int GobAlignment = 64;
|
|
||||||
|
|
||||||
enum CopyFlags
|
enum CopyFlags
|
||||||
{
|
{
|
||||||
SrcLinear = 1 << 7,
|
SrcLinear = 1 << 7,
|
||||||
|
@ -32,14 +29,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
{
|
{
|
||||||
if (linear)
|
if (linear)
|
||||||
{
|
{
|
||||||
int alignWidth = StrideAlignment / bpp;
|
int alignWidth = Constants.StrideAlignment / bpp;
|
||||||
return tex.RegionX == 0 &&
|
return tex.RegionX == 0 &&
|
||||||
tex.RegionY == 0 &&
|
tex.RegionY == 0 &&
|
||||||
stride / bpp == BitUtils.AlignUp(cbp.XCount, alignWidth);
|
stride / bpp == BitUtils.AlignUp(cbp.XCount, alignWidth);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int alignWidth = GobAlignment / bpp;
|
int alignWidth = Constants.GobAlignment / bpp;
|
||||||
return tex.RegionX == 0 &&
|
return tex.RegionX == 0 &&
|
||||||
tex.RegionY == 0 &&
|
tex.RegionY == 0 &&
|
||||||
tex.Width == BitUtils.AlignUp(cbp.XCount, alignWidth) &&
|
tex.Width == BitUtils.AlignUp(cbp.XCount, alignWidth) &&
|
||||||
|
|
|
@ -231,8 +231,21 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
result = TextureViewCompatibility.CopyOnly;
|
result = TextureViewCompatibility.CopyOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (size.Width == otherSize.Width &&
|
if (size.Width == otherSize.Width && size.Height == otherSize.Height)
|
||||||
size.Height == otherSize.Height) ? result : TextureViewCompatibility.Incompatible;
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (lhs.IsLinear && rhs.IsLinear)
|
||||||
|
{
|
||||||
|
// Copy between linear textures with matching stride.
|
||||||
|
int stride = BitUtils.AlignUp(Math.Max(1, lhs.Stride >> level), Constants.StrideAlignment);
|
||||||
|
|
||||||
|
return stride == rhs.Stride ? TextureViewCompatibility.CopyOnly : TextureViewCompatibility.Incompatible;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TextureViewCompatibility.Incompatible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -372,8 +385,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
// For block linear textures, the stride is ignored.
|
// For block linear textures, the stride is ignored.
|
||||||
if (rhs.IsLinear)
|
if (rhs.IsLinear)
|
||||||
{
|
{
|
||||||
int width = Math.Max(1, lhs.Width >> level);
|
int stride = Math.Max(1, lhs.Stride >> level);
|
||||||
int stride = width * lhs.FormatInfo.BytesPerPixel;
|
|
||||||
stride = BitUtils.AlignUp(stride, 32);
|
stride = BitUtils.AlignUp(stride, 32);
|
||||||
|
|
||||||
return stride == rhs.Stride;
|
return stride == rhs.Stride;
|
||||||
|
|
|
@ -16,9 +16,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class TextureGroup : IDisposable
|
class TextureGroup : IDisposable
|
||||||
{
|
{
|
||||||
private const int StrideAlignment = 32;
|
|
||||||
private const int GobAlignment = 64;
|
|
||||||
|
|
||||||
private delegate void HandlesCallbackDelegate(int baseHandle, int regionCount, bool split = false);
|
private delegate void HandlesCallbackDelegate(int baseHandle, int regionCount, bool split = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -429,7 +429,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
// Discount square textures that aren't depth-stencil like. (excludes game textures, cubemap faces, most 3D texture LUT, texture atlas)
|
// Discount square textures that aren't depth-stencil like. (excludes game textures, cubemap faces, most 3D texture LUT, texture atlas)
|
||||||
// Detect if the texture is possibly square. Widths may be aligned, so to remove the uncertainty we align both the width and height.
|
// Detect if the texture is possibly square. Widths may be aligned, so to remove the uncertainty we align both the width and height.
|
||||||
|
|
||||||
int widthAlignment = (info.IsLinear ? 32 : 64) / info.FormatInfo.BytesPerPixel;
|
int widthAlignment = (info.IsLinear ? Constants.StrideAlignment : Constants.GobAlignment) / info.FormatInfo.BytesPerPixel;
|
||||||
|
|
||||||
bool possiblySquare = BitUtils.AlignUp(info.Width, widthAlignment) == BitUtils.AlignUp(info.Height, widthAlignment);
|
bool possiblySquare = BitUtils.AlignUp(info.Width, widthAlignment) == BitUtils.AlignUp(info.Height, widthAlignment);
|
||||||
|
|
||||||
|
@ -977,8 +977,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
// Copy only compatibility, or target texture is already a view.
|
// Copy only compatibility, or target texture is already a view.
|
||||||
|
|
||||||
ChangeSizeIfNeeded(overlapInfo, overlap, false, sizeHint); // Force a size match for copy
|
|
||||||
|
|
||||||
overlap.SynchronizeMemory();
|
overlap.SynchronizeMemory();
|
||||||
texture.CreateCopyDependency(overlap, oInfo.FirstLayer, oInfo.FirstLevel, false);
|
texture.CreateCopyDependency(overlap, oInfo.FirstLayer, oInfo.FirstLevel, false);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue