Move texture anisotropy check to SetInfo (#2843)
Rather than calculating this for every sampler, this PR calculates if a texture can force anisotropy when its info is set, and exposes the value via a public boolean. This should help texture/sampler heavy games when anisotropic filtering is not Auto, like UE4 ones (or so i hear?). There is another cost where samplers are created twice when anisotropic filtering is enabled, but I'm not sure how relevant this one is.
This commit is contained in:
parent
650cc41c02
commit
bc4e70b6fa
2 changed files with 28 additions and 23 deletions
|
@ -1,6 +1,5 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
|
@ -9,8 +8,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Sampler : IDisposable
|
class Sampler : IDisposable
|
||||||
{
|
{
|
||||||
private const int MinLevelsForAnisotropic = 5;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host sampler object.
|
/// Host sampler object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -96,26 +93,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// <returns>A host sampler</returns>
|
/// <returns>A host sampler</returns>
|
||||||
public ISampler GetHostSampler(Texture texture)
|
public ISampler GetHostSampler(Texture texture)
|
||||||
{
|
{
|
||||||
return _anisoSampler != null && AllowForceAnisotropy(texture) ? _anisoSampler : _hostSampler;
|
return _anisoSampler != null && texture?.CanForceAnisotropy == true ? _anisoSampler : _hostSampler;
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determine if the given texture can have anisotropic filtering forced.
|
|
||||||
/// Filtered textures that we might want to force anisotropy on should have a lot of mip levels.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="texture">The texture</param>
|
|
||||||
/// <returns>True if anisotropic filtering can be forced, false otherwise</returns>
|
|
||||||
private static bool AllowForceAnisotropy(Texture texture)
|
|
||||||
{
|
|
||||||
if (texture == null || !(texture.Target == Target.Texture2D || texture.Target == Target.Texture2DArray))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int maxSize = Math.Max(texture.Info.Width, texture.Info.Height);
|
|
||||||
int maxLevels = BitOperations.Log2((uint)maxSize) + 1;
|
|
||||||
|
|
||||||
return texture.Info.Levels >= Math.Min(MinLevelsForAnisotropic, maxLevels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -10,6 +10,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
|
@ -23,6 +24,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
// This method uses much more memory so we want to avoid it if possible.
|
// This method uses much more memory so we want to avoid it if possible.
|
||||||
private const int ByteComparisonSwitchThreshold = 4;
|
private const int ByteComparisonSwitchThreshold = 4;
|
||||||
|
|
||||||
|
private const int MinLevelsForForceAnisotropy = 5;
|
||||||
|
|
||||||
private struct TexturePoolOwner
|
private struct TexturePoolOwner
|
||||||
{
|
{
|
||||||
public TexturePool Pool;
|
public TexturePool Pool;
|
||||||
|
@ -49,6 +52,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TextureInfo Info { get; private set; }
|
public TextureInfo Info { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set when anisotropic filtering can be forced on the given texture.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanForceAnisotropy { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host scale factor.
|
/// Host scale factor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1129,6 +1137,24 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine if this texture can have anisotropic filtering forced.
|
||||||
|
/// Filtered textures that we might want to force anisotropy on should have a lot of mip levels.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if anisotropic filtering can be forced, false otherwise</returns>
|
||||||
|
private bool CanTextureForceAnisotropy()
|
||||||
|
{
|
||||||
|
if (!(Target == Target.Texture2D || Target == Target.Texture2DArray))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxSize = Math.Max(Info.Width, Info.Height);
|
||||||
|
int maxLevels = BitOperations.Log2((uint)maxSize) + 1;
|
||||||
|
|
||||||
|
return Info.Levels >= Math.Min(MinLevelsForForceAnisotropy, maxLevels);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if this texture and the specified target have the same number of dimensions.
|
/// Check if this texture and the specified target have the same number of dimensions.
|
||||||
/// For the purposes of this comparison, 2D and 2D Multisample textures are not considered to have
|
/// For the purposes of this comparison, 2D and 2D Multisample textures are not considered to have
|
||||||
|
@ -1219,6 +1245,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
Target = info.Target;
|
Target = info.Target;
|
||||||
|
CanForceAnisotropy = CanTextureForceAnisotropy();
|
||||||
|
|
||||||
_depth = info.GetDepth();
|
_depth = info.GetDepth();
|
||||||
_layers = info.GetLayers();
|
_layers = info.GetLayers();
|
||||||
|
|
Loading…
Reference in a new issue