SamplerDescriptor.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using Ryujinx.Graphics.GAL;
  2. namespace Ryujinx.Graphics.Gpu.Image
  3. {
  4. /// <summary>
  5. /// Maxwell sampler descriptor structure.
  6. /// This structure defines the sampler descriptor as it is packed on the GPU sampler pool region.
  7. /// </summary>
  8. struct SamplerDescriptor
  9. {
  10. private static readonly float[] _f5ToF32ConversionLut = new float[]
  11. {
  12. 0.0f,
  13. 0.055555556f,
  14. 0.1f,
  15. 0.13636364f,
  16. 0.16666667f,
  17. 0.1923077f,
  18. 0.21428572f,
  19. 0.23333333f,
  20. 0.25f,
  21. 0.2777778f,
  22. 0.3f,
  23. 0.3181818f,
  24. 0.33333334f,
  25. 0.34615386f,
  26. 0.35714287f,
  27. 0.36666667f,
  28. 0.375f,
  29. 0.3888889f,
  30. 0.4f,
  31. 0.4090909f,
  32. 0.41666666f,
  33. 0.42307693f,
  34. 0.42857143f,
  35. 0.43333334f,
  36. 0.4375f,
  37. 0.44444445f,
  38. 0.45f,
  39. 0.45454547f,
  40. 0.45833334f,
  41. 0.46153846f,
  42. 0.4642857f,
  43. 0.46666667f
  44. };
  45. private static readonly float[] _maxAnisotropyLut = new float[]
  46. {
  47. 1, 2, 4, 6, 8, 10, 12, 16
  48. };
  49. private const float Frac8ToF32 = 1.0f / 256.0f;
  50. public uint Word0;
  51. public uint Word1;
  52. public uint Word2;
  53. public uint Word3;
  54. public uint BorderColorR;
  55. public uint BorderColorG;
  56. public uint BorderColorB;
  57. public uint BorderColorA;
  58. /// <summary>
  59. /// Unpacks the texture wrap mode along the X axis.
  60. /// </summary>
  61. /// <returns>The texture wrap mode enum</returns>
  62. public AddressMode UnpackAddressU()
  63. {
  64. return (AddressMode)(Word0 & 7);
  65. }
  66. // <summary>
  67. /// Unpacks the texture wrap mode along the Y axis.
  68. /// </summary>
  69. /// <returns>The texture wrap mode enum</returns>
  70. public AddressMode UnpackAddressV()
  71. {
  72. return (AddressMode)((Word0 >> 3) & 7);
  73. }
  74. // <summary>
  75. /// Unpacks the texture wrap mode along the Z axis.
  76. /// </summary>
  77. /// <returns>The texture wrap mode enum</returns>
  78. public AddressMode UnpackAddressP()
  79. {
  80. return (AddressMode)((Word0 >> 6) & 7);
  81. }
  82. /// <summary>
  83. /// Unpacks the compare mode used for depth comparison on the shader, for
  84. /// depth buffer texture.
  85. /// This is only relevant for shaders with shadow samplers.
  86. /// </summary>
  87. /// <returns>The depth comparison mode enum</returns>
  88. public CompareMode UnpackCompareMode()
  89. {
  90. return (CompareMode)((Word0 >> 9) & 1);
  91. }
  92. /// <summary>
  93. /// Unpacks the compare operation used for depth comparison on the shader, for
  94. /// depth buffer texture.
  95. /// This is only relevant for shaders with shadow samplers.
  96. /// </summary>
  97. /// <returns>The depth comparison operation enum</returns>
  98. public CompareOp UnpackCompareOp()
  99. {
  100. return (CompareOp)(((Word0 >> 10) & 7) + 1);
  101. }
  102. /// <summary>
  103. /// Unpacks and converts the maximum anisotropy value used for texture anisotropic filtering.
  104. /// </summary>
  105. /// <returns>The maximum anisotropy</returns>
  106. public float UnpackMaxAnisotropy()
  107. {
  108. return _maxAnisotropyLut[(Word0 >> 20) & 7];
  109. }
  110. /// <summary>
  111. /// Unpacks the texture magnification filter.
  112. /// This defines the filtering used when the texture covers an area on the screen
  113. /// that is larger than the texture size.
  114. /// </summary>
  115. /// <returns>The magnification filter</returns>
  116. public MagFilter UnpackMagFilter()
  117. {
  118. return (MagFilter)(Word1 & 3);
  119. }
  120. /// <summary>
  121. /// Unpacks the texture minification filter.
  122. /// This defines the filtering used when the texture covers an area on the screen
  123. /// that is smaller than the texture size.
  124. /// </summary>
  125. /// <returns>The minification filter</returns>
  126. public MinFilter UnpackMinFilter()
  127. {
  128. SamplerMinFilter minFilter = (SamplerMinFilter)((Word1 >> 4) & 3);
  129. SamplerMipFilter mipFilter = (SamplerMipFilter)((Word1 >> 6) & 3);
  130. return ConvertFilter(minFilter, mipFilter);
  131. }
  132. /// <summary>
  133. /// Converts two minification and filter enum, to a single minification enum,
  134. /// including mipmap filtering information, as expected from the host API.
  135. /// </summary>
  136. /// <param name="minFilter">The minification filter</param>
  137. /// <param name="mipFilter">The mipmap level filter</param>
  138. /// <returns>The combined, host API compatible filter enum</returns>
  139. private static MinFilter ConvertFilter(SamplerMinFilter minFilter, SamplerMipFilter mipFilter)
  140. {
  141. switch (mipFilter)
  142. {
  143. case SamplerMipFilter.None:
  144. switch (minFilter)
  145. {
  146. case SamplerMinFilter.Nearest: return MinFilter.Nearest;
  147. case SamplerMinFilter.Linear: return MinFilter.Linear;
  148. }
  149. break;
  150. case SamplerMipFilter.Nearest:
  151. switch (minFilter)
  152. {
  153. case SamplerMinFilter.Nearest: return MinFilter.NearestMipmapNearest;
  154. case SamplerMinFilter.Linear: return MinFilter.LinearMipmapNearest;
  155. }
  156. break;
  157. case SamplerMipFilter.Linear:
  158. switch (minFilter)
  159. {
  160. case SamplerMinFilter.Nearest: return MinFilter.NearestMipmapLinear;
  161. case SamplerMinFilter.Linear: return MinFilter.LinearMipmapLinear;
  162. }
  163. break;
  164. }
  165. return MinFilter.Nearest;
  166. }
  167. /// <summary>
  168. /// Unpacks the reduction filter, used with texture minification linear filtering.
  169. /// This describes how the final value will be computed from neighbouring pixels.
  170. /// </summary>
  171. /// <returns>The reduction filter</returns>
  172. public ReductionFilter UnpackReductionFilter()
  173. {
  174. return (ReductionFilter)((Word1 >> 10) & 3);
  175. }
  176. /// <summary>
  177. /// Unpacks the level-of-detail bias value.
  178. /// This is a bias added to the level-of-detail value as computed by the GPU, used to select
  179. /// which mipmap level to use from a given texture.
  180. /// </summary>
  181. /// <returns>The level-of-detail bias value</returns>
  182. public float UnpackMipLodBias()
  183. {
  184. int fixedValue = (int)(Word1 >> 12) & 0x1fff;
  185. fixedValue = (fixedValue << 19) >> 19;
  186. return fixedValue * Frac8ToF32;
  187. }
  188. /// <summary>
  189. /// Unpacks the level-of-detail snap value.
  190. /// </summary>
  191. /// <returns>The level-of-detail snap value</returns>
  192. public float UnpackLodSnap()
  193. {
  194. return _f5ToF32ConversionLut[(Word1 >> 26) & 0x1f];
  195. }
  196. /// <summary>
  197. /// Unpacks the minimum level-of-detail value.
  198. /// </summary>
  199. /// <returns>The minimum level-of-detail value</returns>
  200. public float UnpackMinLod()
  201. {
  202. return (Word2 & 0xfff) * Frac8ToF32;
  203. }
  204. /// <summary>
  205. /// Unpacks the maximum level-of-detail value.
  206. /// </summary>
  207. /// <returns>The maximum level-of-detail value</returns>
  208. public float UnpackMaxLod()
  209. {
  210. return ((Word2 >> 12) & 0xfff) * Frac8ToF32;
  211. }
  212. }
  213. }