mirror of
https://git.ryujinx.app/kenji-nx/ryujinx.git
synced 2025-12-18 01:37:04 +00:00
Revert PRs 7226(1.1.1385), 7311(1.1.1392), and 7312 (1.1.1396).
* "Vulkan: Feedback loop detection and barriers (#7226)" * "Change image format view handling to allow view incompatible formats (#7311)" * "Add support for sampler sRGB disable (#7312)" * These changes prevent slowdowns in several areas in Paper Mario: The Thousand Year Door, possibly other games.
This commit is contained in:
parent
a2c0035013
commit
02a5f75fab
49 changed files with 358 additions and 879 deletions
|
|
@ -75,76 +75,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
private readonly ConcurrentQueue<DereferenceRequest> _dereferenceQueue = new();
|
||||
private TextureDescriptor _defaultDescriptor;
|
||||
|
||||
/// <summary>
|
||||
/// List of textures that shares the same memory region, but have different formats.
|
||||
/// </summary>
|
||||
private class TextureAliasList
|
||||
{
|
||||
/// <summary>
|
||||
/// Alias texture.
|
||||
/// </summary>
|
||||
/// <param name="Format">Texture format</param>
|
||||
/// <param name="Texture">Texture</param>
|
||||
private readonly record struct Alias(Format Format, Texture Texture);
|
||||
|
||||
/// <summary>
|
||||
/// List of texture aliases.
|
||||
/// </summary>
|
||||
private readonly List<Alias> _aliases;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the texture alias list.
|
||||
/// </summary>
|
||||
public TextureAliasList()
|
||||
{
|
||||
_aliases = new List<Alias>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new texture alias.
|
||||
/// </summary>
|
||||
/// <param name="format">Alias format</param>
|
||||
/// <param name="texture">Alias texture</param>
|
||||
public void Add(Format format, Texture texture)
|
||||
{
|
||||
_aliases.Add(new Alias(format, texture));
|
||||
texture.IncrementReferenceCount();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a texture with the requested format, or returns null if not found.
|
||||
/// </summary>
|
||||
/// <param name="format">Format to find</param>
|
||||
/// <returns>Texture with the requested format, or null if not found</returns>
|
||||
public Texture Find(Format format)
|
||||
{
|
||||
foreach (var alias in _aliases)
|
||||
{
|
||||
if (alias.Format == format)
|
||||
{
|
||||
return alias.Texture;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all alias textures.
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
foreach (var entry in _aliases)
|
||||
{
|
||||
entry.Texture.DecrementReferenceCount();
|
||||
}
|
||||
|
||||
_aliases.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<Texture, TextureAliasList> _aliasLists;
|
||||
|
||||
/// <summary>
|
||||
/// Linked list node used on the texture pool cache.
|
||||
/// </summary>
|
||||
|
|
@ -165,7 +95,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
public TexturePool(GpuContext context, GpuChannel channel, ulong address, int maximumId) : base(context, channel.MemoryManager.Physical, address, maximumId)
|
||||
{
|
||||
_channel = channel;
|
||||
_aliasLists = new Dictionary<Texture, TextureAliasList>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -186,13 +115,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
if (texture == null)
|
||||
{
|
||||
TextureInfo info = GetInfo(descriptor, out int layerSize);
|
||||
|
||||
// The dereference queue can put our texture back on the cache.
|
||||
if ((texture = ProcessDereferenceQueue(id)) != null)
|
||||
{
|
||||
return ref descriptor;
|
||||
}
|
||||
|
||||
TextureInfo info = GetInfo(descriptor, out int layerSize);
|
||||
texture = PhysicalMemory.TextureCache.FindOrCreateTexture(_channel.MemoryManager, TextureSearchFlags.ForSampler, info, layerSize);
|
||||
|
||||
// If this happens, then the texture address is invalid, we can't add it to the cache.
|
||||
|
|
@ -227,17 +157,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <returns>The texture with the given ID</returns>
|
||||
public override Texture Get(int id)
|
||||
{
|
||||
return Get(id, srgbSampler: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||
/// <returns>The texture with the given ID</returns>
|
||||
public Texture Get(int id, bool srgbSampler)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
|
|
@ -251,7 +170,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
SynchronizeMemory();
|
||||
}
|
||||
|
||||
GetForBinding(id, srgbSampler, out Texture texture);
|
||||
GetInternal(id, out Texture texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
|
@ -263,10 +182,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// This method assumes that the pool has been manually synchronized before doing binding.
|
||||
/// </remarks>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||
/// <param name="texture">The texture with the given ID</param>
|
||||
/// <returns>The texture descriptor with the given ID</returns>
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, bool srgbSampler, out Texture texture)
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, out Texture texture)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
|
|
@ -276,66 +194,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
|
||||
// When getting for binding, assume the pool has already been synchronized.
|
||||
|
||||
if (!srgbSampler)
|
||||
{
|
||||
// If the sampler does not have the sRGB bit enabled, then the texture can't use a sRGB format.
|
||||
ref readonly TextureDescriptor tempDescriptor = ref GetDescriptorRef(id);
|
||||
|
||||
if (tempDescriptor.UnpackSrgb() && FormatTable.TryGetTextureFormat(tempDescriptor.UnpackFormat(), isSrgb: false, out FormatInfo formatInfo))
|
||||
{
|
||||
// Get a view of the texture with the right format.
|
||||
return ref GetForBinding(id, formatInfo, out texture);
|
||||
}
|
||||
}
|
||||
|
||||
return ref GetInternal(id, out texture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the texture descriptor and texture with the given ID.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method assumes that the pool has been manually synchronized before doing binding.
|
||||
/// </remarks>
|
||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||
/// <param name="formatInfo">Texture format information</param>
|
||||
/// <param name="texture">The texture with the given ID</param>
|
||||
/// <returns>The texture descriptor with the given ID</returns>
|
||||
public ref readonly TextureDescriptor GetForBinding(int id, FormatInfo formatInfo, out Texture texture)
|
||||
{
|
||||
if ((uint)id >= Items.Length)
|
||||
{
|
||||
texture = null;
|
||||
return ref _defaultDescriptor;
|
||||
}
|
||||
|
||||
ref readonly TextureDescriptor descriptor = ref GetInternal(id, out texture);
|
||||
|
||||
if (texture != null && formatInfo.Format != 0 && texture.Format != formatInfo.Format)
|
||||
{
|
||||
if (!_aliasLists.TryGetValue(texture, out TextureAliasList aliasList))
|
||||
{
|
||||
_aliasLists.Add(texture, aliasList = new TextureAliasList());
|
||||
}
|
||||
|
||||
texture = aliasList.Find(formatInfo.Format);
|
||||
|
||||
if (texture == null)
|
||||
{
|
||||
TextureInfo info = GetInfo(descriptor, out int layerSize);
|
||||
info = ChangeFormat(info, formatInfo);
|
||||
texture = PhysicalMemory.TextureCache.FindOrCreateTexture(_channel.MemoryManager, TextureSearchFlags.ForSampler, info, layerSize);
|
||||
|
||||
if (texture != null)
|
||||
{
|
||||
aliasList.Add(formatInfo.Format, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ref descriptor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the pool was modified, and returns the last sequence number where a modification was detected.
|
||||
/// </summary>
|
||||
|
|
@ -373,7 +234,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
else
|
||||
{
|
||||
texture.DecrementReferenceCount();
|
||||
RemoveAliasList(texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -467,8 +327,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
{
|
||||
texture.DecrementReferenceCount();
|
||||
}
|
||||
|
||||
RemoveAliasList(texture);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -511,7 +369,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
if (Interlocked.Exchange(ref Items[id], null) != null)
|
||||
{
|
||||
texture.DecrementReferenceCount(this, id);
|
||||
RemoveAliasList(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -765,57 +622,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
component == SwizzleComponent.Green;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the format on the texture information structure, and also adjusts the width for the new format if needed.
|
||||
/// </summary>
|
||||
/// <param name="info">Texture information</param>
|
||||
/// <param name="dstFormat">New format</param>
|
||||
/// <returns>Texture information with the new format</returns>
|
||||
private static TextureInfo ChangeFormat(in TextureInfo info, FormatInfo dstFormat)
|
||||
{
|
||||
int width = info.Width;
|
||||
|
||||
if (info.FormatInfo.BytesPerPixel != dstFormat.BytesPerPixel)
|
||||
{
|
||||
int stride = width * info.FormatInfo.BytesPerPixel;
|
||||
width = stride / dstFormat.BytesPerPixel;
|
||||
}
|
||||
|
||||
return new TextureInfo(
|
||||
info.GpuAddress,
|
||||
width,
|
||||
info.Height,
|
||||
info.DepthOrLayers,
|
||||
info.Levels,
|
||||
info.SamplesInX,
|
||||
info.SamplesInY,
|
||||
info.Stride,
|
||||
info.IsLinear,
|
||||
info.GobBlocksInY,
|
||||
info.GobBlocksInZ,
|
||||
info.GobBlocksInTileX,
|
||||
info.Target,
|
||||
dstFormat,
|
||||
info.DepthStencilMode,
|
||||
info.SwizzleR,
|
||||
info.SwizzleG,
|
||||
info.SwizzleB,
|
||||
info.SwizzleA);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all aliases for a texture.
|
||||
/// </summary>
|
||||
/// <param name="texture">Texture to have the aliases removed</param>
|
||||
private void RemoveAliasList(Texture texture)
|
||||
{
|
||||
if (_aliasLists.TryGetValue(texture, out TextureAliasList aliasList))
|
||||
{
|
||||
_aliasLists.Remove(texture);
|
||||
aliasList.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decrements the reference count of the texture.
|
||||
/// This indicates that the texture pool is not using it anymore.
|
||||
|
|
@ -823,11 +629,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||
/// <param name="item">The texture to be deleted</param>
|
||||
protected override void Delete(Texture item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
item.DecrementReferenceCount(this);
|
||||
RemoveAliasList(item);
|
||||
}
|
||||
item?.DecrementReferenceCount(this);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue