diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Image/Sampler.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/Sampler.cs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs b/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs new file mode 100644 index 00000000..b70ac9eb --- /dev/null +++ b/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs @@ -0,0 +1,115 @@ +using Ryujinx.Graphics.GAL; +using System; + +namespace Ryujinx.Graphics.Gpu.Image +{ + /// <summary> + /// Cached sampler entry for sampler pools. + /// </summary> + class Sampler : IDisposable + { + /// <summary> + /// True if the sampler is disposed, false otherwise. + /// </summary> + public bool IsDisposed { get; private set; } + + /// <summary> + /// Host sampler object. + /// </summary> + private readonly ISampler _hostSampler; + + /// <summary> + /// Host sampler object, with anisotropy forced. + /// </summary> + private readonly ISampler _anisoSampler; + + /// <summary> + /// Creates a new instance of the cached sampler. + /// </summary> + /// <param name="context">The GPU context the sampler belongs to</param> + /// <param name="descriptor">The Maxwell sampler descriptor</param> + public Sampler(GpuContext context, SamplerDescriptor descriptor) + { + MinFilter minFilter = descriptor.UnpackMinFilter(); + MagFilter magFilter = descriptor.UnpackMagFilter(); + + bool seamlessCubemap = descriptor.UnpackSeamlessCubemap(); + + AddressMode addressU = descriptor.UnpackAddressU(); + AddressMode addressV = descriptor.UnpackAddressV(); + AddressMode addressP = descriptor.UnpackAddressP(); + + CompareMode compareMode = descriptor.UnpackCompareMode(); + CompareOp compareOp = descriptor.UnpackCompareOp(); + + ColorF color = new ColorF( + descriptor.BorderColorR, + descriptor.BorderColorG, + descriptor.BorderColorB, + descriptor.BorderColorA); + + float minLod = descriptor.UnpackMinLod(); + float maxLod = descriptor.UnpackMaxLod(); + float mipLodBias = descriptor.UnpackMipLodBias(); + + float maxRequestedAnisotropy = descriptor.UnpackMaxAnisotropy(); + float maxSupportedAnisotropy = context.Capabilities.MaximumSupportedAnisotropy; + + _hostSampler = context.Renderer.CreateSampler(new SamplerCreateInfo( + minFilter, + magFilter, + seamlessCubemap, + addressU, + addressV, + addressP, + compareMode, + compareOp, + color, + minLod, + maxLod, + mipLodBias, + Math.Min(maxRequestedAnisotropy, maxSupportedAnisotropy))); + + if (GraphicsConfig.MaxAnisotropy >= 0 && GraphicsConfig.MaxAnisotropy <= 16 && (minFilter == MinFilter.LinearMipmapNearest || minFilter == MinFilter.LinearMipmapLinear)) + { + maxRequestedAnisotropy = GraphicsConfig.MaxAnisotropy; + + _anisoSampler = context.Renderer.CreateSampler(new SamplerCreateInfo( + minFilter, + magFilter, + seamlessCubemap, + addressU, + addressV, + addressP, + compareMode, + compareOp, + color, + minLod, + maxLod, + mipLodBias, + Math.Min(maxRequestedAnisotropy, maxSupportedAnisotropy))); + } + } + + /// <summary> + /// Gets a host sampler for the given texture. + /// </summary> + /// <param name="texture">Texture to be sampled</param> + /// <returns>A host sampler</returns> + public ISampler GetHostSampler(Texture texture) + { + return _anisoSampler != null && texture?.CanForceAnisotropy == true ? _anisoSampler : _hostSampler; + } + + /// <summary> + /// Disposes the host sampler object. + /// </summary> + public void Dispose() + { + IsDisposed = true; + + _hostSampler.Dispose(); + _anisoSampler?.Dispose(); + } + } +}
\ No newline at end of file |