/ src / Ryujinx.Graphics.Gpu / Image / Sampler.cs
Sampler.cs
  1  using Ryujinx.Graphics.GAL;
  2  using System;
  3  
  4  namespace Ryujinx.Graphics.Gpu.Image
  5  {
  6      /// <summary>
  7      /// Cached sampler entry for sampler pools.
  8      /// </summary>
  9      class Sampler : IDisposable
 10      {
 11          /// <summary>
 12          /// True if the sampler is disposed, false otherwise.
 13          /// </summary>
 14          public bool IsDisposed { get; private set; }
 15  
 16          /// <summary>
 17          /// True if the sampler has sRGB conversion enabled, false otherwise.
 18          /// </summary>
 19          public bool IsSrgb { get; }
 20  
 21          /// <summary>
 22          /// Host sampler object.
 23          /// </summary>
 24          private readonly ISampler _hostSampler;
 25  
 26          /// <summary>
 27          /// Host sampler object, with anisotropy forced.
 28          /// </summary>
 29          private readonly ISampler _anisoSampler;
 30  
 31          /// <summary>
 32          /// Creates a new instance of the cached sampler.
 33          /// </summary>
 34          /// <param name="context">The GPU context the sampler belongs to</param>
 35          /// <param name="descriptor">The Maxwell sampler descriptor</param>
 36          public Sampler(GpuContext context, SamplerDescriptor descriptor)
 37          {
 38              IsSrgb = descriptor.UnpackSrgb();
 39  
 40              MinFilter minFilter = descriptor.UnpackMinFilter();
 41              MagFilter magFilter = descriptor.UnpackMagFilter();
 42  
 43              bool seamlessCubemap = descriptor.UnpackSeamlessCubemap();
 44  
 45              AddressMode addressU = descriptor.UnpackAddressU();
 46              AddressMode addressV = descriptor.UnpackAddressV();
 47              AddressMode addressP = descriptor.UnpackAddressP();
 48  
 49              CompareMode compareMode = descriptor.UnpackCompareMode();
 50              CompareOp compareOp = descriptor.UnpackCompareOp();
 51  
 52              ColorF color = new(
 53                  descriptor.BorderColorR,
 54                  descriptor.BorderColorG,
 55                  descriptor.BorderColorB,
 56                  descriptor.BorderColorA);
 57  
 58              float minLod = descriptor.UnpackMinLod();
 59              float maxLod = descriptor.UnpackMaxLod();
 60              float mipLodBias = descriptor.UnpackMipLodBias();
 61  
 62              float maxRequestedAnisotropy = descriptor.UnpackMaxAnisotropy();
 63              float maxSupportedAnisotropy = context.Capabilities.MaximumSupportedAnisotropy;
 64  
 65              _hostSampler = context.Renderer.CreateSampler(new SamplerCreateInfo(
 66                  minFilter,
 67                  magFilter,
 68                  seamlessCubemap,
 69                  addressU,
 70                  addressV,
 71                  addressP,
 72                  compareMode,
 73                  compareOp,
 74                  color,
 75                  minLod,
 76                  maxLod,
 77                  mipLodBias,
 78                  Math.Min(maxRequestedAnisotropy, maxSupportedAnisotropy)));
 79  
 80              if (GraphicsConfig.MaxAnisotropy >= 0 && GraphicsConfig.MaxAnisotropy <= 16 && (minFilter == MinFilter.LinearMipmapNearest || minFilter == MinFilter.LinearMipmapLinear))
 81              {
 82                  maxRequestedAnisotropy = GraphicsConfig.MaxAnisotropy;
 83  
 84                  _anisoSampler = context.Renderer.CreateSampler(new SamplerCreateInfo(
 85                      minFilter,
 86                      magFilter,
 87                      seamlessCubemap,
 88                      addressU,
 89                      addressV,
 90                      addressP,
 91                      compareMode,
 92                      compareOp,
 93                      color,
 94                      minLod,
 95                      maxLod,
 96                      mipLodBias,
 97                      Math.Min(maxRequestedAnisotropy, maxSupportedAnisotropy)));
 98              }
 99          }
100  
101          /// <summary>
102          /// Gets a host sampler for the given texture.
103          /// </summary>
104          /// <param name="texture">Texture to be sampled</param>
105          /// <returns>A host sampler</returns>
106          public ISampler GetHostSampler(Texture texture)
107          {
108              return _anisoSampler != null && texture?.CanForceAnisotropy == true ? _anisoSampler : _hostSampler;
109          }
110  
111          /// <summary>
112          /// Disposes the host sampler object.
113          /// </summary>
114          public void Dispose()
115          {
116              IsDisposed = true;
117  
118              _hostSampler.Dispose();
119              _anisoSampler?.Dispose();
120          }
121      }
122  }