EnumConversion.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.Graphics.GAL;
  3. using SharpMetal.Metal;
  4. using System;
  5. using System.Runtime.Versioning;
  6. namespace Ryujinx.Graphics.Metal
  7. {
  8. [SupportedOSPlatform("macos")]
  9. static class EnumConversion
  10. {
  11. public static MTLSamplerAddressMode Convert(this AddressMode mode)
  12. {
  13. return mode switch
  14. {
  15. AddressMode.Clamp => MTLSamplerAddressMode.ClampToEdge, // TODO: Should be clamp.
  16. AddressMode.Repeat => MTLSamplerAddressMode.Repeat,
  17. AddressMode.MirrorClamp => MTLSamplerAddressMode.MirrorClampToEdge, // TODO: Should be mirror clamp.
  18. AddressMode.MirroredRepeat => MTLSamplerAddressMode.MirrorRepeat,
  19. AddressMode.ClampToBorder => MTLSamplerAddressMode.ClampToBorderColor,
  20. AddressMode.ClampToEdge => MTLSamplerAddressMode.ClampToEdge,
  21. AddressMode.MirrorClampToEdge => MTLSamplerAddressMode.MirrorClampToEdge,
  22. AddressMode.MirrorClampToBorder => MTLSamplerAddressMode.ClampToBorderColor, // TODO: Should be mirror clamp to border.
  23. _ => LogInvalidAndReturn(mode, nameof(AddressMode), MTLSamplerAddressMode.ClampToEdge) // TODO: Should be clamp.
  24. };
  25. }
  26. public static MTLBlendFactor Convert(this BlendFactor factor)
  27. {
  28. return factor switch
  29. {
  30. BlendFactor.Zero or BlendFactor.ZeroGl => MTLBlendFactor.Zero,
  31. BlendFactor.One or BlendFactor.OneGl => MTLBlendFactor.One,
  32. BlendFactor.SrcColor or BlendFactor.SrcColorGl => MTLBlendFactor.SourceColor,
  33. BlendFactor.OneMinusSrcColor or BlendFactor.OneMinusSrcColorGl => MTLBlendFactor.OneMinusSourceColor,
  34. BlendFactor.SrcAlpha or BlendFactor.SrcAlphaGl => MTLBlendFactor.SourceAlpha,
  35. BlendFactor.OneMinusSrcAlpha or BlendFactor.OneMinusSrcAlphaGl => MTLBlendFactor.OneMinusSourceAlpha,
  36. BlendFactor.DstAlpha or BlendFactor.DstAlphaGl => MTLBlendFactor.DestinationAlpha,
  37. BlendFactor.OneMinusDstAlpha or BlendFactor.OneMinusDstAlphaGl => MTLBlendFactor.OneMinusDestinationAlpha,
  38. BlendFactor.DstColor or BlendFactor.DstColorGl => MTLBlendFactor.DestinationColor,
  39. BlendFactor.OneMinusDstColor or BlendFactor.OneMinusDstColorGl => MTLBlendFactor.OneMinusDestinationColor,
  40. BlendFactor.SrcAlphaSaturate or BlendFactor.SrcAlphaSaturateGl => MTLBlendFactor.SourceAlphaSaturated,
  41. BlendFactor.Src1Color or BlendFactor.Src1ColorGl => MTLBlendFactor.Source1Color,
  42. BlendFactor.OneMinusSrc1Color or BlendFactor.OneMinusSrc1ColorGl => MTLBlendFactor.OneMinusSource1Color,
  43. BlendFactor.Src1Alpha or BlendFactor.Src1AlphaGl => MTLBlendFactor.Source1Alpha,
  44. BlendFactor.OneMinusSrc1Alpha or BlendFactor.OneMinusSrc1AlphaGl => MTLBlendFactor.OneMinusSource1Alpha,
  45. BlendFactor.ConstantColor => MTLBlendFactor.BlendColor,
  46. BlendFactor.OneMinusConstantColor => MTLBlendFactor.OneMinusBlendColor,
  47. BlendFactor.ConstantAlpha => MTLBlendFactor.BlendAlpha,
  48. BlendFactor.OneMinusConstantAlpha => MTLBlendFactor.OneMinusBlendAlpha,
  49. _ => LogInvalidAndReturn(factor, nameof(BlendFactor), MTLBlendFactor.Zero)
  50. };
  51. }
  52. public static MTLBlendOperation Convert(this BlendOp op)
  53. {
  54. return op switch
  55. {
  56. BlendOp.Add or BlendOp.AddGl => MTLBlendOperation.Add,
  57. BlendOp.Subtract or BlendOp.SubtractGl => MTLBlendOperation.Subtract,
  58. BlendOp.ReverseSubtract or BlendOp.ReverseSubtractGl => MTLBlendOperation.ReverseSubtract,
  59. BlendOp.Minimum => MTLBlendOperation.Min,
  60. BlendOp.Maximum => MTLBlendOperation.Max,
  61. _ => LogInvalidAndReturn(op, nameof(BlendOp), MTLBlendOperation.Add)
  62. };
  63. }
  64. public static MTLCompareFunction Convert(this CompareOp op)
  65. {
  66. return op switch
  67. {
  68. CompareOp.Never or CompareOp.NeverGl => MTLCompareFunction.Never,
  69. CompareOp.Less or CompareOp.LessGl => MTLCompareFunction.Less,
  70. CompareOp.Equal or CompareOp.EqualGl => MTLCompareFunction.Equal,
  71. CompareOp.LessOrEqual or CompareOp.LessOrEqualGl => MTLCompareFunction.LessEqual,
  72. CompareOp.Greater or CompareOp.GreaterGl => MTLCompareFunction.Greater,
  73. CompareOp.NotEqual or CompareOp.NotEqualGl => MTLCompareFunction.NotEqual,
  74. CompareOp.GreaterOrEqual or CompareOp.GreaterOrEqualGl => MTLCompareFunction.GreaterEqual,
  75. CompareOp.Always or CompareOp.AlwaysGl => MTLCompareFunction.Always,
  76. _ => LogInvalidAndReturn(op, nameof(CompareOp), MTLCompareFunction.Never)
  77. };
  78. }
  79. public static MTLCullMode Convert(this Face face)
  80. {
  81. return face switch
  82. {
  83. Face.Back => MTLCullMode.Back,
  84. Face.Front => MTLCullMode.Front,
  85. Face.FrontAndBack => MTLCullMode.None,
  86. _ => LogInvalidAndReturn(face, nameof(Face), MTLCullMode.Back)
  87. };
  88. }
  89. public static MTLWinding Convert(this FrontFace frontFace)
  90. {
  91. // The viewport is flipped vertically, therefore we need to switch the winding order as well
  92. return frontFace switch
  93. {
  94. FrontFace.Clockwise => MTLWinding.CounterClockwise,
  95. FrontFace.CounterClockwise => MTLWinding.Clockwise,
  96. _ => LogInvalidAndReturn(frontFace, nameof(FrontFace), MTLWinding.Clockwise)
  97. };
  98. }
  99. public static MTLIndexType Convert(this IndexType type)
  100. {
  101. return type switch
  102. {
  103. IndexType.UShort => MTLIndexType.UInt16,
  104. IndexType.UInt => MTLIndexType.UInt32,
  105. _ => LogInvalidAndReturn(type, nameof(IndexType), MTLIndexType.UInt16)
  106. };
  107. }
  108. public static MTLLogicOperation Convert(this LogicalOp op)
  109. {
  110. return op switch
  111. {
  112. LogicalOp.Clear => MTLLogicOperation.Clear,
  113. LogicalOp.And => MTLLogicOperation.And,
  114. LogicalOp.AndReverse => MTLLogicOperation.AndReverse,
  115. LogicalOp.Copy => MTLLogicOperation.Copy,
  116. LogicalOp.AndInverted => MTLLogicOperation.AndInverted,
  117. LogicalOp.Noop => MTLLogicOperation.Noop,
  118. LogicalOp.Xor => MTLLogicOperation.Xor,
  119. LogicalOp.Or => MTLLogicOperation.Or,
  120. LogicalOp.Nor => MTLLogicOperation.Nor,
  121. LogicalOp.Equiv => MTLLogicOperation.Equivalence,
  122. LogicalOp.Invert => MTLLogicOperation.Invert,
  123. LogicalOp.OrReverse => MTLLogicOperation.OrReverse,
  124. LogicalOp.CopyInverted => MTLLogicOperation.CopyInverted,
  125. LogicalOp.OrInverted => MTLLogicOperation.OrInverted,
  126. LogicalOp.Nand => MTLLogicOperation.Nand,
  127. LogicalOp.Set => MTLLogicOperation.Set,
  128. _ => LogInvalidAndReturn(op, nameof(LogicalOp), MTLLogicOperation.And)
  129. };
  130. }
  131. public static MTLSamplerMinMagFilter Convert(this MagFilter filter)
  132. {
  133. return filter switch
  134. {
  135. MagFilter.Nearest => MTLSamplerMinMagFilter.Nearest,
  136. MagFilter.Linear => MTLSamplerMinMagFilter.Linear,
  137. _ => LogInvalidAndReturn(filter, nameof(MagFilter), MTLSamplerMinMagFilter.Nearest)
  138. };
  139. }
  140. public static (MTLSamplerMinMagFilter, MTLSamplerMipFilter) Convert(this MinFilter filter)
  141. {
  142. return filter switch
  143. {
  144. MinFilter.Nearest => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest),
  145. MinFilter.Linear => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Linear),
  146. MinFilter.NearestMipmapNearest => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest),
  147. MinFilter.LinearMipmapNearest => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Nearest),
  148. MinFilter.NearestMipmapLinear => (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Linear),
  149. MinFilter.LinearMipmapLinear => (MTLSamplerMinMagFilter.Linear, MTLSamplerMipFilter.Linear),
  150. _ => LogInvalidAndReturn(filter, nameof(MinFilter), (MTLSamplerMinMagFilter.Nearest, MTLSamplerMipFilter.Nearest))
  151. };
  152. }
  153. public static MTLPrimitiveType Convert(this PrimitiveTopology topology)
  154. {
  155. return topology switch
  156. {
  157. PrimitiveTopology.Points => MTLPrimitiveType.Point,
  158. PrimitiveTopology.Lines => MTLPrimitiveType.Line,
  159. PrimitiveTopology.LineStrip => MTLPrimitiveType.LineStrip,
  160. PrimitiveTopology.Triangles => MTLPrimitiveType.Triangle,
  161. PrimitiveTopology.TriangleStrip => MTLPrimitiveType.TriangleStrip,
  162. _ => LogInvalidAndReturn(topology, nameof(PrimitiveTopology), MTLPrimitiveType.Triangle)
  163. };
  164. }
  165. public static MTLStencilOperation Convert(this StencilOp op)
  166. {
  167. return op switch
  168. {
  169. StencilOp.Keep or StencilOp.KeepGl => MTLStencilOperation.Keep,
  170. StencilOp.Zero or StencilOp.ZeroGl => MTLStencilOperation.Zero,
  171. StencilOp.Replace or StencilOp.ReplaceGl => MTLStencilOperation.Replace,
  172. StencilOp.IncrementAndClamp or StencilOp.IncrementAndClampGl => MTLStencilOperation.IncrementClamp,
  173. StencilOp.DecrementAndClamp or StencilOp.DecrementAndClampGl => MTLStencilOperation.DecrementClamp,
  174. StencilOp.Invert or StencilOp.InvertGl => MTLStencilOperation.Invert,
  175. StencilOp.IncrementAndWrap or StencilOp.IncrementAndWrapGl => MTLStencilOperation.IncrementWrap,
  176. StencilOp.DecrementAndWrap or StencilOp.DecrementAndWrapGl => MTLStencilOperation.DecrementWrap,
  177. _ => LogInvalidAndReturn(op, nameof(StencilOp), MTLStencilOperation.Keep)
  178. };
  179. }
  180. public static MTLTextureType Convert(this Target target)
  181. {
  182. return target switch
  183. {
  184. Target.TextureBuffer => MTLTextureType.TextureBuffer,
  185. Target.Texture1D => MTLTextureType.Type1D,
  186. Target.Texture1DArray => MTLTextureType.Type1DArray,
  187. Target.Texture2D => MTLTextureType.Type2D,
  188. Target.Texture2DArray => MTLTextureType.Type2DArray,
  189. Target.Texture2DMultisample => MTLTextureType.Type2DMultisample,
  190. Target.Texture2DMultisampleArray => MTLTextureType.Type2DMultisampleArray,
  191. Target.Texture3D => MTLTextureType.Type3D,
  192. Target.Cubemap => MTLTextureType.Cube,
  193. Target.CubemapArray => MTLTextureType.CubeArray,
  194. _ => LogInvalidAndReturn(target, nameof(Target), MTLTextureType.Type2D)
  195. };
  196. }
  197. public static MTLTextureSwizzle Convert(this SwizzleComponent swizzleComponent)
  198. {
  199. return swizzleComponent switch
  200. {
  201. SwizzleComponent.Zero => MTLTextureSwizzle.Zero,
  202. SwizzleComponent.One => MTLTextureSwizzle.One,
  203. SwizzleComponent.Red => MTLTextureSwizzle.Red,
  204. SwizzleComponent.Green => MTLTextureSwizzle.Green,
  205. SwizzleComponent.Blue => MTLTextureSwizzle.Blue,
  206. SwizzleComponent.Alpha => MTLTextureSwizzle.Alpha,
  207. _ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), MTLTextureSwizzle.Zero)
  208. };
  209. }
  210. public static MTLVertexFormat Convert(this Format format)
  211. {
  212. return format switch
  213. {
  214. Format.R16Float => MTLVertexFormat.Half,
  215. Format.R16G16Float => MTLVertexFormat.Half2,
  216. Format.R16G16B16Float => MTLVertexFormat.Half3,
  217. Format.R16G16B16A16Float => MTLVertexFormat.Half4,
  218. Format.R32Float => MTLVertexFormat.Float,
  219. Format.R32G32Float => MTLVertexFormat.Float2,
  220. Format.R32G32B32Float => MTLVertexFormat.Float3,
  221. Format.R11G11B10Float => MTLVertexFormat.FloatRG11B10,
  222. Format.R32G32B32A32Float => MTLVertexFormat.Float4,
  223. Format.R8Uint => MTLVertexFormat.UChar,
  224. Format.R8G8Uint => MTLVertexFormat.UChar2,
  225. Format.R8G8B8Uint => MTLVertexFormat.UChar3,
  226. Format.R8G8B8A8Uint => MTLVertexFormat.UChar4,
  227. Format.R16Uint => MTLVertexFormat.UShort,
  228. Format.R16G16Uint => MTLVertexFormat.UShort2,
  229. Format.R16G16B16Uint => MTLVertexFormat.UShort3,
  230. Format.R16G16B16A16Uint => MTLVertexFormat.UShort4,
  231. Format.R32Uint => MTLVertexFormat.UInt,
  232. Format.R32G32Uint => MTLVertexFormat.UInt2,
  233. Format.R32G32B32Uint => MTLVertexFormat.UInt3,
  234. Format.R32G32B32A32Uint => MTLVertexFormat.UInt4,
  235. Format.R8Sint => MTLVertexFormat.Char,
  236. Format.R8G8Sint => MTLVertexFormat.Char2,
  237. Format.R8G8B8Sint => MTLVertexFormat.Char3,
  238. Format.R8G8B8A8Sint => MTLVertexFormat.Char4,
  239. Format.R16Sint => MTLVertexFormat.Short,
  240. Format.R16G16Sint => MTLVertexFormat.Short2,
  241. Format.R16G16B16Sint => MTLVertexFormat.Short3,
  242. Format.R16G16B16A16Sint => MTLVertexFormat.Short4,
  243. Format.R32Sint => MTLVertexFormat.Int,
  244. Format.R32G32Sint => MTLVertexFormat.Int2,
  245. Format.R32G32B32Sint => MTLVertexFormat.Int3,
  246. Format.R32G32B32A32Sint => MTLVertexFormat.Int4,
  247. Format.R8Unorm => MTLVertexFormat.UCharNormalized,
  248. Format.R8G8Unorm => MTLVertexFormat.UChar2Normalized,
  249. Format.R8G8B8Unorm => MTLVertexFormat.UChar3Normalized,
  250. Format.R8G8B8A8Unorm => MTLVertexFormat.UChar4Normalized,
  251. Format.R16Unorm => MTLVertexFormat.UShortNormalized,
  252. Format.R16G16Unorm => MTLVertexFormat.UShort2Normalized,
  253. Format.R16G16B16Unorm => MTLVertexFormat.UShort3Normalized,
  254. Format.R16G16B16A16Unorm => MTLVertexFormat.UShort4Normalized,
  255. Format.R10G10B10A2Unorm => MTLVertexFormat.UInt1010102Normalized,
  256. Format.R8Snorm => MTLVertexFormat.CharNormalized,
  257. Format.R8G8Snorm => MTLVertexFormat.Char2Normalized,
  258. Format.R8G8B8Snorm => MTLVertexFormat.Char3Normalized,
  259. Format.R8G8B8A8Snorm => MTLVertexFormat.Char4Normalized,
  260. Format.R16Snorm => MTLVertexFormat.ShortNormalized,
  261. Format.R16G16Snorm => MTLVertexFormat.Short2Normalized,
  262. Format.R16G16B16Snorm => MTLVertexFormat.Short3Normalized,
  263. Format.R16G16B16A16Snorm => MTLVertexFormat.Short4Normalized,
  264. Format.R10G10B10A2Snorm => MTLVertexFormat.Int1010102Normalized,
  265. _ => LogInvalidAndReturn(format, nameof(Format), MTLVertexFormat.Float4)
  266. };
  267. }
  268. private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
  269. {
  270. Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
  271. return defaultValue;
  272. }
  273. }
  274. }