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 }