using OpenTK.Graphics.OpenGL; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; namespace Ryujinx.Graphics.OpenGL { static class EnumConversion { public static TextureWrapMode Convert(this AddressMode mode) { switch (mode) { case AddressMode.Clamp: return TextureWrapMode.Clamp; case AddressMode.Repeat: return TextureWrapMode.Repeat; case AddressMode.MirrorClamp: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt; case AddressMode.MirrorClampToEdge: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt; case AddressMode.MirrorClampToBorder: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt; case AddressMode.ClampToBorder: return TextureWrapMode.ClampToBorder; case AddressMode.MirroredRepeat: return TextureWrapMode.MirroredRepeat; case AddressMode.ClampToEdge: return TextureWrapMode.ClampToEdge; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AddressMode)} enum value: {mode}."); return TextureWrapMode.Clamp; } public static NvBlendEquationAdvanced Convert(this AdvancedBlendOp op) { switch (op) { case AdvancedBlendOp.Zero: return NvBlendEquationAdvanced.Zero; case AdvancedBlendOp.Src: return NvBlendEquationAdvanced.SrcNv; case AdvancedBlendOp.Dst: return NvBlendEquationAdvanced.DstNv; case AdvancedBlendOp.SrcOver: return NvBlendEquationAdvanced.SrcOverNv; case AdvancedBlendOp.DstOver: return NvBlendEquationAdvanced.DstOverNv; case AdvancedBlendOp.SrcIn: return NvBlendEquationAdvanced.SrcInNv; case AdvancedBlendOp.DstIn: return NvBlendEquationAdvanced.DstInNv; case AdvancedBlendOp.SrcOut: return NvBlendEquationAdvanced.SrcOutNv; case AdvancedBlendOp.DstOut: return NvBlendEquationAdvanced.DstOutNv; case AdvancedBlendOp.SrcAtop: return NvBlendEquationAdvanced.SrcAtopNv; case AdvancedBlendOp.DstAtop: return NvBlendEquationAdvanced.DstAtopNv; case AdvancedBlendOp.Xor: return NvBlendEquationAdvanced.XorNv; case AdvancedBlendOp.Plus: return NvBlendEquationAdvanced.PlusNv; case AdvancedBlendOp.PlusClamped: return NvBlendEquationAdvanced.PlusClampedNv; case AdvancedBlendOp.PlusClampedAlpha: return NvBlendEquationAdvanced.PlusClampedAlphaNv; case AdvancedBlendOp.PlusDarker: return NvBlendEquationAdvanced.PlusDarkerNv; case AdvancedBlendOp.Multiply: return NvBlendEquationAdvanced.MultiplyNv; case AdvancedBlendOp.Screen: return NvBlendEquationAdvanced.ScreenNv; case AdvancedBlendOp.Overlay: return NvBlendEquationAdvanced.OverlayNv; case AdvancedBlendOp.Darken: return NvBlendEquationAdvanced.DarkenNv; case AdvancedBlendOp.Lighten: return NvBlendEquationAdvanced.LightenNv; case AdvancedBlendOp.ColorDodge: return NvBlendEquationAdvanced.ColordodgeNv; case AdvancedBlendOp.ColorBurn: return NvBlendEquationAdvanced.ColorburnNv; case AdvancedBlendOp.HardLight: return NvBlendEquationAdvanced.HardlightNv; case AdvancedBlendOp.SoftLight: return NvBlendEquationAdvanced.SoftlightNv; case AdvancedBlendOp.Difference: return NvBlendEquationAdvanced.DifferenceNv; case AdvancedBlendOp.Minus: return NvBlendEquationAdvanced.MinusNv; case AdvancedBlendOp.MinusClamped: return NvBlendEquationAdvanced.MinusClampedNv; case AdvancedBlendOp.Exclusion: return NvBlendEquationAdvanced.ExclusionNv; case AdvancedBlendOp.Contrast: return NvBlendEquationAdvanced.ContrastNv; case AdvancedBlendOp.Invert: return NvBlendEquationAdvanced.Invert; case AdvancedBlendOp.InvertRGB: return NvBlendEquationAdvanced.InvertRgbNv; case AdvancedBlendOp.InvertOvg: return NvBlendEquationAdvanced.InvertOvgNv; case AdvancedBlendOp.LinearDodge: return NvBlendEquationAdvanced.LineardodgeNv; case AdvancedBlendOp.LinearBurn: return NvBlendEquationAdvanced.LinearburnNv; case AdvancedBlendOp.VividLight: return NvBlendEquationAdvanced.VividlightNv; case AdvancedBlendOp.LinearLight: return NvBlendEquationAdvanced.LinearlightNv; case AdvancedBlendOp.PinLight: return NvBlendEquationAdvanced.PinlightNv; case AdvancedBlendOp.HardMix: return NvBlendEquationAdvanced.HardmixNv; case AdvancedBlendOp.Red: return NvBlendEquationAdvanced.RedNv; case AdvancedBlendOp.Green: return NvBlendEquationAdvanced.GreenNv; case AdvancedBlendOp.Blue: return NvBlendEquationAdvanced.BlueNv; case AdvancedBlendOp.HslHue: return NvBlendEquationAdvanced.HslHueNv; case AdvancedBlendOp.HslSaturation: return NvBlendEquationAdvanced.HslSaturationNv; case AdvancedBlendOp.HslColor: return NvBlendEquationAdvanced.HslColorNv; case AdvancedBlendOp.HslLuminosity: return NvBlendEquationAdvanced.HslLuminosityNv; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOp)} enum value: {op}."); return NvBlendEquationAdvanced.Zero; } public static All Convert(this AdvancedBlendOverlap overlap) { switch (overlap) { case AdvancedBlendOverlap.Uncorrelated: return All.UncorrelatedNv; case AdvancedBlendOverlap.Disjoint: return All.DisjointNv; case AdvancedBlendOverlap.Conjoint: return All.ConjointNv; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOverlap)} enum value: {overlap}."); return All.UncorrelatedNv; } public static All Convert(this BlendFactor factor) { switch (factor) { case BlendFactor.Zero: case BlendFactor.ZeroGl: return All.Zero; case BlendFactor.One: case BlendFactor.OneGl: return All.One; case BlendFactor.SrcColor: case BlendFactor.SrcColorGl: return All.SrcColor; case BlendFactor.OneMinusSrcColor: case BlendFactor.OneMinusSrcColorGl: return All.OneMinusSrcColor; case BlendFactor.SrcAlpha: case BlendFactor.SrcAlphaGl: return All.SrcAlpha; case BlendFactor.OneMinusSrcAlpha: case BlendFactor.OneMinusSrcAlphaGl: return All.OneMinusSrcAlpha; case BlendFactor.DstAlpha: case BlendFactor.DstAlphaGl: return All.DstAlpha; case BlendFactor.OneMinusDstAlpha: case BlendFactor.OneMinusDstAlphaGl: return All.OneMinusDstAlpha; case BlendFactor.DstColor: case BlendFactor.DstColorGl: return All.DstColor; case BlendFactor.OneMinusDstColor: case BlendFactor.OneMinusDstColorGl: return All.OneMinusDstColor; case BlendFactor.SrcAlphaSaturate: case BlendFactor.SrcAlphaSaturateGl: return All.SrcAlphaSaturate; case BlendFactor.Src1Color: case BlendFactor.Src1ColorGl: return All.Src1Color; case BlendFactor.OneMinusSrc1Color: case BlendFactor.OneMinusSrc1ColorGl: return All.OneMinusSrc1Color; case BlendFactor.Src1Alpha: case BlendFactor.Src1AlphaGl: return All.Src1Alpha; case BlendFactor.OneMinusSrc1Alpha: case BlendFactor.OneMinusSrc1AlphaGl: return All.OneMinusSrc1Alpha; case BlendFactor.ConstantColor: return All.ConstantColor; case BlendFactor.OneMinusConstantColor: return All.OneMinusConstantColor; case BlendFactor.ConstantAlpha: return All.ConstantAlpha; case BlendFactor.OneMinusConstantAlpha: return All.OneMinusConstantAlpha; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(BlendFactor)} enum value: {factor}."); return All.Zero; } public static BlendEquationMode Convert(this BlendOp op) { switch (op) { case BlendOp.Add: case BlendOp.AddGl: return BlendEquationMode.FuncAdd; case BlendOp.Minimum: case BlendOp.MinimumGl: return BlendEquationMode.Min; case BlendOp.Maximum: case BlendOp.MaximumGl: return BlendEquationMode.Max; case BlendOp.Subtract: case BlendOp.SubtractGl: return BlendEquationMode.FuncSubtract; case BlendOp.ReverseSubtract: case BlendOp.ReverseSubtractGl: return BlendEquationMode.FuncReverseSubtract; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(BlendOp)} enum value: {op}."); return BlendEquationMode.FuncAdd; } public static TextureCompareMode Convert(this CompareMode mode) { switch (mode) { case CompareMode.None: return TextureCompareMode.None; case CompareMode.CompareRToTexture: return TextureCompareMode.CompareRToTexture; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(CompareMode)} enum value: {mode}."); return TextureCompareMode.None; } public static All Convert(this CompareOp op) { switch (op) { case CompareOp.Never: case CompareOp.NeverGl: return All.Never; case CompareOp.Less: case CompareOp.LessGl: return All.Less; case CompareOp.Equal: case CompareOp.EqualGl: return All.Equal; case CompareOp.LessOrEqual: case CompareOp.LessOrEqualGl: return All.Lequal; case CompareOp.Greater: case CompareOp.GreaterGl: return All.Greater; case CompareOp.NotEqual: case CompareOp.NotEqualGl: return All.Notequal; case CompareOp.GreaterOrEqual: case CompareOp.GreaterOrEqualGl: return All.Gequal; case CompareOp.Always: case CompareOp.AlwaysGl: return All.Always; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(CompareOp)} enum value: {op}."); return All.Never; } public static ClipDepthMode Convert(this DepthMode mode) { switch (mode) { case DepthMode.MinusOneToOne: return ClipDepthMode.NegativeOneToOne; case DepthMode.ZeroToOne: return ClipDepthMode.ZeroToOne; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(DepthMode)} enum value: {mode}."); return ClipDepthMode.NegativeOneToOne; } public static All Convert(this DepthStencilMode mode) { switch (mode) { case DepthStencilMode.Depth: return All.DepthComponent; case DepthStencilMode.Stencil: return All.StencilIndex; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(DepthStencilMode)} enum value: {mode}."); return All.Depth; } public static CullFaceMode Convert(this Face face) { switch (face) { case Face.Back: return CullFaceMode.Back; case Face.Front: return CullFaceMode.Front; case Face.FrontAndBack: return CullFaceMode.FrontAndBack; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(Face)} enum value: {face}."); return CullFaceMode.Back; } public static FrontFaceDirection Convert(this FrontFace frontFace) { switch (frontFace) { case FrontFace.Clockwise: return FrontFaceDirection.Cw; case FrontFace.CounterClockwise: return FrontFaceDirection.Ccw; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(FrontFace)} enum value: {frontFace}."); return FrontFaceDirection.Cw; } public static DrawElementsType Convert(this IndexType type) { switch (type) { case IndexType.UByte: return DrawElementsType.UnsignedByte; case IndexType.UShort: return DrawElementsType.UnsignedShort; case IndexType.UInt: return DrawElementsType.UnsignedInt; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(IndexType)} enum value: {type}."); return DrawElementsType.UnsignedByte; } public static TextureMagFilter Convert(this MagFilter filter) { switch (filter) { case MagFilter.Nearest: return TextureMagFilter.Nearest; case MagFilter.Linear: return TextureMagFilter.Linear; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(MagFilter)} enum value: {filter}."); return TextureMagFilter.Nearest; } public static TextureMinFilter Convert(this MinFilter filter) { switch (filter) { case MinFilter.Nearest: return TextureMinFilter.Nearest; case MinFilter.Linear: return TextureMinFilter.Linear; case MinFilter.NearestMipmapNearest: return TextureMinFilter.NearestMipmapNearest; case MinFilter.LinearMipmapNearest: return TextureMinFilter.LinearMipmapNearest; case MinFilter.NearestMipmapLinear: return TextureMinFilter.NearestMipmapLinear; case MinFilter.LinearMipmapLinear: return TextureMinFilter.LinearMipmapLinear; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(MinFilter)} enum value: {filter}."); return TextureMinFilter.Nearest; } public static OpenTK.Graphics.OpenGL.PolygonMode Convert(this GAL.PolygonMode mode) { switch (mode) { case GAL.PolygonMode.Point: return OpenTK.Graphics.OpenGL.PolygonMode.Point; case GAL.PolygonMode.Line: return OpenTK.Graphics.OpenGL.PolygonMode.Line; case GAL.PolygonMode.Fill: return OpenTK.Graphics.OpenGL.PolygonMode.Fill; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(GAL.PolygonMode)} enum value: {mode}."); return OpenTK.Graphics.OpenGL.PolygonMode.Fill; } public static PrimitiveType Convert(this PrimitiveTopology topology) { switch (topology) { case PrimitiveTopology.Points: return PrimitiveType.Points; case PrimitiveTopology.Lines: return PrimitiveType.Lines; case PrimitiveTopology.LineLoop: return PrimitiveType.LineLoop; case PrimitiveTopology.LineStrip: return PrimitiveType.LineStrip; case PrimitiveTopology.Triangles: return PrimitiveType.Triangles; case PrimitiveTopology.TriangleStrip: return PrimitiveType.TriangleStrip; case PrimitiveTopology.TriangleFan: return PrimitiveType.TriangleFan; case PrimitiveTopology.Quads: return PrimitiveType.Quads; case PrimitiveTopology.QuadStrip: return PrimitiveType.QuadStrip; case PrimitiveTopology.Polygon: return PrimitiveType.TriangleFan; case PrimitiveTopology.LinesAdjacency: return PrimitiveType.LinesAdjacency; case PrimitiveTopology.LineStripAdjacency: return PrimitiveType.LineStripAdjacency; case PrimitiveTopology.TrianglesAdjacency: return PrimitiveType.TrianglesAdjacency; case PrimitiveTopology.TriangleStripAdjacency: return PrimitiveType.TriangleStripAdjacency; case PrimitiveTopology.Patches: return PrimitiveType.Patches; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(PrimitiveTopology)} enum value: {topology}."); return PrimitiveType.Points; } public static TransformFeedbackPrimitiveType ConvertToTfType(this PrimitiveTopology topology) { switch (topology) { case PrimitiveTopology.Points: return TransformFeedbackPrimitiveType.Points; case PrimitiveTopology.Lines: case PrimitiveTopology.LineLoop: case PrimitiveTopology.LineStrip: case PrimitiveTopology.LinesAdjacency: case PrimitiveTopology.LineStripAdjacency: return TransformFeedbackPrimitiveType.Lines; case PrimitiveTopology.Triangles: case PrimitiveTopology.TriangleStrip: case PrimitiveTopology.TriangleFan: case PrimitiveTopology.TrianglesAdjacency: case PrimitiveTopology.TriangleStripAdjacency: return TransformFeedbackPrimitiveType.Triangles; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(PrimitiveTopology)} enum value: {topology}."); return TransformFeedbackPrimitiveType.Points; } public static OpenTK.Graphics.OpenGL.StencilOp Convert(this GAL.StencilOp op) { switch (op) { case GAL.StencilOp.Keep: case GAL.StencilOp.KeepGl: return OpenTK.Graphics.OpenGL.StencilOp.Keep; case GAL.StencilOp.Zero: case GAL.StencilOp.ZeroGl: return OpenTK.Graphics.OpenGL.StencilOp.Zero; case GAL.StencilOp.Replace: case GAL.StencilOp.ReplaceGl: return OpenTK.Graphics.OpenGL.StencilOp.Replace; case GAL.StencilOp.IncrementAndClamp: case GAL.StencilOp.IncrementAndClampGl: return OpenTK.Graphics.OpenGL.StencilOp.Incr; case GAL.StencilOp.DecrementAndClamp: case GAL.StencilOp.DecrementAndClampGl: return OpenTK.Graphics.OpenGL.StencilOp.Decr; case GAL.StencilOp.Invert: case GAL.StencilOp.InvertGl: return OpenTK.Graphics.OpenGL.StencilOp.Invert; case GAL.StencilOp.IncrementAndWrap: case GAL.StencilOp.IncrementAndWrapGl: return OpenTK.Graphics.OpenGL.StencilOp.IncrWrap; case GAL.StencilOp.DecrementAndWrap: case GAL.StencilOp.DecrementAndWrapGl: return OpenTK.Graphics.OpenGL.StencilOp.DecrWrap; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(GAL.StencilOp)} enum value: {op}."); return OpenTK.Graphics.OpenGL.StencilOp.Keep; } public static All Convert(this SwizzleComponent swizzleComponent) { switch (swizzleComponent) { case SwizzleComponent.Zero: return All.Zero; case SwizzleComponent.One: return All.One; case SwizzleComponent.Red: return All.Red; case SwizzleComponent.Green: return All.Green; case SwizzleComponent.Blue: return All.Blue; case SwizzleComponent.Alpha: return All.Alpha; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(SwizzleComponent)} enum value: {swizzleComponent}."); return All.Zero; } public static ImageTarget ConvertToImageTarget(this Target target) { return (ImageTarget)target.Convert(); } public static TextureTarget Convert(this Target target) { switch (target) { case Target.Texture1D: return TextureTarget.Texture1D; case Target.Texture2D: return TextureTarget.Texture2D; case Target.Texture3D: return TextureTarget.Texture3D; case Target.Texture1DArray: return TextureTarget.Texture1DArray; case Target.Texture2DArray: return TextureTarget.Texture2DArray; case Target.Texture2DMultisample: return TextureTarget.Texture2DMultisample; case Target.Texture2DMultisampleArray: return TextureTarget.Texture2DMultisampleArray; case Target.Cubemap: return TextureTarget.TextureCubeMap; case Target.CubemapArray: return TextureTarget.TextureCubeMapArray; case Target.TextureBuffer: return TextureTarget.TextureBuffer; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(Target)} enum value: {target}."); return TextureTarget.Texture2D; } public static NvViewportSwizzle Convert(this ViewportSwizzle swizzle) { switch (swizzle) { case ViewportSwizzle.PositiveX: return NvViewportSwizzle.ViewportSwizzlePositiveXNv; case ViewportSwizzle.PositiveY: return NvViewportSwizzle.ViewportSwizzlePositiveYNv; case ViewportSwizzle.PositiveZ: return NvViewportSwizzle.ViewportSwizzlePositiveZNv; case ViewportSwizzle.PositiveW: return NvViewportSwizzle.ViewportSwizzlePositiveWNv; case ViewportSwizzle.NegativeX: return NvViewportSwizzle.ViewportSwizzleNegativeXNv; case ViewportSwizzle.NegativeY: return NvViewportSwizzle.ViewportSwizzleNegativeYNv; case ViewportSwizzle.NegativeZ: return NvViewportSwizzle.ViewportSwizzleNegativeZNv; case ViewportSwizzle.NegativeW: return NvViewportSwizzle.ViewportSwizzleNegativeWNv; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(ViewportSwizzle)} enum value: {swizzle}."); return NvViewportSwizzle.ViewportSwizzlePositiveXNv; } public static All Convert(this LogicalOp op) { switch (op) { case LogicalOp.Clear: return All.Clear; case LogicalOp.And: return All.And; case LogicalOp.AndReverse: return All.AndReverse; case LogicalOp.Copy: return All.Copy; case LogicalOp.AndInverted: return All.AndInverted; case LogicalOp.Noop: return All.Noop; case LogicalOp.Xor: return All.Xor; case LogicalOp.Or: return All.Or; case LogicalOp.Nor: return All.Nor; case LogicalOp.Equiv: return All.Equiv; case LogicalOp.Invert: return All.Invert; case LogicalOp.OrReverse: return All.OrReverse; case LogicalOp.CopyInverted: return All.CopyInverted; case LogicalOp.OrInverted: return All.OrInverted; case LogicalOp.Nand: return All.Nand; case LogicalOp.Set: return All.Set; } Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(LogicalOp)} enum value: {op}."); return All.Never; } public static ShaderType Convert(this ShaderStage stage) { return stage switch { ShaderStage.Compute => ShaderType.ComputeShader, ShaderStage.Vertex => ShaderType.VertexShader, ShaderStage.TessellationControl => ShaderType.TessControlShader, ShaderStage.TessellationEvaluation => ShaderType.TessEvaluationShader, ShaderStage.Geometry => ShaderType.GeometryShader, ShaderStage.Fragment => ShaderType.FragmentShader, _ => ShaderType.VertexShader }; } } }