using OpenTK.Graphics.OpenGL; using System; namespace Ryujinx.Graphics.Gal.OpenGL { static class OGLEnumConverter { public static FrontFaceDirection GetFrontFace(GalFrontFace FrontFace) { switch (FrontFace) { case GalFrontFace.CW: return FrontFaceDirection.Cw; case GalFrontFace.CCW: return FrontFaceDirection.Ccw; } throw new ArgumentException(nameof(FrontFace) + " \"" + FrontFace + "\" is not valid!"); } public static CullFaceMode GetCullFace(GalCullFace CullFace) { switch (CullFace) { case GalCullFace.Front: return CullFaceMode.Front; case GalCullFace.Back: return CullFaceMode.Back; case GalCullFace.FrontAndBack: return CullFaceMode.FrontAndBack; } throw new ArgumentException(nameof(CullFace) + " \"" + CullFace + "\" is not valid!"); } public static StencilOp GetStencilOp(GalStencilOp Op) { switch (Op) { case GalStencilOp.Keep: return StencilOp.Keep; case GalStencilOp.Zero: return StencilOp.Zero; case GalStencilOp.Replace: return StencilOp.Replace; case GalStencilOp.Incr: return StencilOp.Incr; case GalStencilOp.Decr: return StencilOp.Decr; case GalStencilOp.Invert: return StencilOp.Invert; case GalStencilOp.IncrWrap: return StencilOp.IncrWrap; case GalStencilOp.DecrWrap: return StencilOp.DecrWrap; } throw new ArgumentException(nameof(Op) + " \"" + Op + "\" is not valid!"); } public static DepthFunction GetDepthFunc(GalComparisonOp Func) { return (DepthFunction)GetFunc(Func); } public static StencilFunction GetStencilFunc(GalComparisonOp Func) { return (StencilFunction)GetFunc(Func); } private static All GetFunc(GalComparisonOp Func) { if ((int)Func >= (int)All.Never && (int)Func <= (int)All.Always) { return (All)Func; } switch (Func) { case GalComparisonOp.Never: return All.Never; case GalComparisonOp.Less: return All.Less; case GalComparisonOp.Equal: return All.Equal; case GalComparisonOp.Lequal: return All.Lequal; case GalComparisonOp.Greater: return All.Greater; case GalComparisonOp.NotEqual: return All.Notequal; case GalComparisonOp.Gequal: return All.Gequal; case GalComparisonOp.Always: return All.Always; } throw new ArgumentException(nameof(Func) + " \"" + Func + "\" is not valid!"); } public static DrawElementsType GetDrawElementsType(GalIndexFormat Format) { switch (Format) { case GalIndexFormat.Byte: return DrawElementsType.UnsignedByte; case GalIndexFormat.Int16: return DrawElementsType.UnsignedShort; case GalIndexFormat.Int32: return DrawElementsType.UnsignedInt; } throw new ArgumentException(nameof(Format) + " \"" + Format + "\" is not valid!"); } public static PrimitiveType GetPrimitiveType(GalPrimitiveType Type) { switch (Type) { case GalPrimitiveType.Points: return PrimitiveType.Points; case GalPrimitiveType.Lines: return PrimitiveType.Lines; case GalPrimitiveType.LineLoop: return PrimitiveType.LineLoop; case GalPrimitiveType.LineStrip: return PrimitiveType.LineStrip; case GalPrimitiveType.Triangles: return PrimitiveType.Triangles; case GalPrimitiveType.TriangleStrip: return PrimitiveType.TriangleStrip; case GalPrimitiveType.TriangleFan: return PrimitiveType.TriangleFan; case GalPrimitiveType.Polygon: return PrimitiveType.Polygon; case GalPrimitiveType.LinesAdjacency: return PrimitiveType.LinesAdjacency; case GalPrimitiveType.LineStripAdjacency: return PrimitiveType.LineStripAdjacency; case GalPrimitiveType.TrianglesAdjacency: return PrimitiveType.TrianglesAdjacency; case GalPrimitiveType.TriangleStripAdjacency: return PrimitiveType.TriangleStripAdjacency; case GalPrimitiveType.Patches: return PrimitiveType.Patches; } throw new ArgumentException(nameof(Type) + " \"" + Type + "\" is not valid!"); } public static ShaderType GetShaderType(GalShaderType Type) { switch (Type) { case GalShaderType.Vertex: return ShaderType.VertexShader; case GalShaderType.TessControl: return ShaderType.TessControlShader; case GalShaderType.TessEvaluation: return ShaderType.TessEvaluationShader; case GalShaderType.Geometry: return ShaderType.GeometryShader; case GalShaderType.Fragment: return ShaderType.FragmentShader; } throw new ArgumentException(nameof(Type) + " \"" + Type + "\" is not valid!"); } public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format) { switch (Format) { case GalImageFormat.RGBA32 | GalImageFormat.Float: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); case GalImageFormat.RGBA32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); case GalImageFormat.RGBA32 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); case GalImageFormat.RGBA16 | GalImageFormat.Float: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); case GalImageFormat.RGBA16 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); case GalImageFormat.RGBA16 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); case GalImageFormat.RGBA16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba16, PixelFormat.Rgba, PixelType.UnsignedShort); case GalImageFormat.RG32 | GalImageFormat.Float: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); case GalImageFormat.RG32 | GalImageFormat.Sint: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); case GalImageFormat.RG32 | GalImageFormat.Uint: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); case GalImageFormat.RGBX8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb8, PixelFormat.Rgba, PixelType.UnsignedByte); case GalImageFormat.RGBA8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); case GalImageFormat.RGBA8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); case GalImageFormat.RGBA8 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); case GalImageFormat.RGBA8 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); case GalImageFormat.RGBA8 | GalImageFormat.Srgb: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); case GalImageFormat.BGRA8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Bgra, PixelType.UnsignedByte); case GalImageFormat.BGRA8 | GalImageFormat.Srgb: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Bgra, PixelType.UnsignedByte); case GalImageFormat.RGBA4 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); case GalImageFormat.RGB10A2 | GalImageFormat.Uint: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); case GalImageFormat.RGB10A2 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); case GalImageFormat.R32 | GalImageFormat.Float: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); case GalImageFormat.BGR5A1 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); case GalImageFormat.RGB5A1 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed); case GalImageFormat.RGB565 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed); case GalImageFormat.BGR565 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); case GalImageFormat.RG16 | GalImageFormat.Float: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); case GalImageFormat.RG16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); case GalImageFormat.RG16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Short); case GalImageFormat.RG16 | GalImageFormat.Uint: return (PixelInternalFormat.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort); case GalImageFormat.RG16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); case GalImageFormat.RG8 | GalImageFormat.Sint: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); case GalImageFormat.RG8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); case GalImageFormat.RG8 | GalImageFormat.Uint: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); case GalImageFormat.RG8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); case GalImageFormat.R16 | GalImageFormat.Float: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); case GalImageFormat.R16 | GalImageFormat.Sint: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); case GalImageFormat.R16 | GalImageFormat.Snorm: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Short); case GalImageFormat.R16 | GalImageFormat.Uint: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); case GalImageFormat.R16 | GalImageFormat.Unorm: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); case GalImageFormat.R8 | GalImageFormat.Sint: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); case GalImageFormat.R8 | GalImageFormat.Snorm: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); case GalImageFormat.R8 | GalImageFormat.Uint: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); case GalImageFormat.R8 | GalImageFormat.Unorm: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); case GalImageFormat.R11G11B10 | GalImageFormat.Float: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); case GalImageFormat.D16 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); case GalImageFormat.D24 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent24, PixelFormat.DepthComponent, PixelType.UnsignedInt); case GalImageFormat.D24S8 | GalImageFormat.Uint: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); case GalImageFormat.D24S8 | GalImageFormat.Unorm: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); case GalImageFormat.D32 | GalImageFormat.Float: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); case GalImageFormat.D32S8 | GalImageFormat.Float: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); } throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}"); } public static InternalFormat GetCompressedImageFormat(GalImageFormat Format) { switch (Format) { case GalImageFormat.BptcSfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcSignedFloat; case GalImageFormat.BptcUfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcUnsignedFloat; case GalImageFormat.BptcUnorm | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaBptcUnorm; case GalImageFormat.BptcUnorm | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaBptcUnorm; case GalImageFormat.BC1 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt1Ext; case GalImageFormat.BC1 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt1Ext; case GalImageFormat.BC2 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt3Ext; case GalImageFormat.BC2 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt3Ext; case GalImageFormat.BC3 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt5Ext; case GalImageFormat.BC3 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt5Ext; case GalImageFormat.BC4 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRedRgtc1; case GalImageFormat.BC4 | GalImageFormat.Unorm: return InternalFormat.CompressedRedRgtc1; case GalImageFormat.BC5 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRgRgtc2; case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2; } throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}"); } public static All GetTextureSwizzle(GalTextureSource Source) { switch (Source) { case GalTextureSource.Zero: return All.Zero; case GalTextureSource.Red: return All.Red; case GalTextureSource.Green: return All.Green; case GalTextureSource.Blue: return All.Blue; case GalTextureSource.Alpha: return All.Alpha; case GalTextureSource.OneInt: return All.One; case GalTextureSource.OneFloat: return All.One; } throw new ArgumentException(nameof(Source) + " \"" + Source + "\" is not valid!"); } public static TextureWrapMode GetTextureWrapMode(GalTextureWrap Wrap) { switch (Wrap) { case GalTextureWrap.Repeat: return TextureWrapMode.Repeat; case GalTextureWrap.MirroredRepeat: return TextureWrapMode.MirroredRepeat; case GalTextureWrap.ClampToEdge: return TextureWrapMode.ClampToEdge; case GalTextureWrap.ClampToBorder: return TextureWrapMode.ClampToBorder; case GalTextureWrap.Clamp: return TextureWrapMode.Clamp; } if (OGLExtension.TextureMirrorClamp) { switch (Wrap) { case GalTextureWrap.MirrorClampToEdge: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt; case GalTextureWrap.MirrorClampToBorder: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt; case GalTextureWrap.MirrorClamp: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt; } } else { //Fallback to non-mirrored clamps switch (Wrap) { case GalTextureWrap.MirrorClampToEdge: return TextureWrapMode.ClampToEdge; case GalTextureWrap.MirrorClampToBorder: return TextureWrapMode.ClampToBorder; case GalTextureWrap.MirrorClamp: return TextureWrapMode.Clamp; } } throw new ArgumentException(nameof(Wrap) + " \"" + Wrap + "\" is not valid!"); } public static TextureMinFilter GetTextureMinFilter( GalTextureFilter MinFilter, GalTextureMipFilter MipFilter) { //TODO: Mip (needs mipmap support first). switch (MinFilter) { case GalTextureFilter.Nearest: return TextureMinFilter.Nearest; case GalTextureFilter.Linear: return TextureMinFilter.Linear; } throw new ArgumentException(nameof(MinFilter) + " \"" + MinFilter + "\" is not valid!"); } public static TextureMagFilter GetTextureMagFilter(GalTextureFilter Filter) { switch (Filter) { case GalTextureFilter.Nearest: return TextureMagFilter.Nearest; case GalTextureFilter.Linear: return TextureMagFilter.Linear; } throw new ArgumentException(nameof(Filter) + " \"" + Filter + "\" is not valid!"); } public static BlendEquationMode GetBlendEquation(GalBlendEquation BlendEquation) { switch (BlendEquation) { case GalBlendEquation.FuncAdd: case GalBlendEquation.FuncAddGl: return BlendEquationMode.FuncAdd; case GalBlendEquation.FuncSubtract: case GalBlendEquation.FuncSubtractGl: return BlendEquationMode.FuncSubtract; case GalBlendEquation.FuncReverseSubtract: case GalBlendEquation.FuncReverseSubtractGl: return BlendEquationMode.FuncReverseSubtract; case GalBlendEquation.Min: case GalBlendEquation.MinGl: return BlendEquationMode.Min; case GalBlendEquation.Max: case GalBlendEquation.MaxGl: return BlendEquationMode.Max; } throw new ArgumentException(nameof(BlendEquation) + " \"" + BlendEquation + "\" is not valid!"); } public static BlendingFactor GetBlendFactor(GalBlendFactor BlendFactor) { switch (BlendFactor) { case GalBlendFactor.Zero: case GalBlendFactor.ZeroGl: return BlendingFactor.Zero; case GalBlendFactor.One: case GalBlendFactor.OneGl: return BlendingFactor.One; case GalBlendFactor.SrcColor: case GalBlendFactor.SrcColorGl: return BlendingFactor.SrcColor; case GalBlendFactor.OneMinusSrcColor: case GalBlendFactor.OneMinusSrcColorGl: return BlendingFactor.OneMinusSrcColor; case GalBlendFactor.DstColor: case GalBlendFactor.DstColorGl: return BlendingFactor.DstColor; case GalBlendFactor.OneMinusDstColor: case GalBlendFactor.OneMinusDstColorGl: return BlendingFactor.OneMinusDstColor; case GalBlendFactor.SrcAlpha: case GalBlendFactor.SrcAlphaGl: return BlendingFactor.SrcAlpha; case GalBlendFactor.OneMinusSrcAlpha: case GalBlendFactor.OneMinusSrcAlphaGl: return BlendingFactor.OneMinusSrcAlpha; case GalBlendFactor.DstAlpha: case GalBlendFactor.DstAlphaGl: return BlendingFactor.DstAlpha; case GalBlendFactor.OneMinusDstAlpha: case GalBlendFactor.OneMinusDstAlphaGl: return BlendingFactor.OneMinusDstAlpha; case GalBlendFactor.OneMinusConstantColor: case GalBlendFactor.OneMinusConstantColorGl: return BlendingFactor.OneMinusConstantColor; case GalBlendFactor.ConstantAlpha: case GalBlendFactor.ConstantAlphaGl: return BlendingFactor.ConstantAlpha; case GalBlendFactor.OneMinusConstantAlpha: case GalBlendFactor.OneMinusConstantAlphaGl: return BlendingFactor.OneMinusConstantAlpha; case GalBlendFactor.SrcAlphaSaturate: case GalBlendFactor.SrcAlphaSaturateGl: return BlendingFactor.SrcAlphaSaturate; case GalBlendFactor.Src1Color: case GalBlendFactor.Src1ColorGl: return BlendingFactor.Src1Color; case GalBlendFactor.OneMinusSrc1Color: case GalBlendFactor.OneMinusSrc1ColorGl: return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Color; case GalBlendFactor.Src1Alpha: case GalBlendFactor.Src1AlphaGl: return BlendingFactor.Src1Alpha; case GalBlendFactor.OneMinusSrc1Alpha: case GalBlendFactor.OneMinusSrc1AlphaGl: return (BlendingFactor)BlendingFactorSrc.OneMinusSrc1Alpha; case GalBlendFactor.ConstantColor: case GalBlendFactor.ConstantColorGl: return BlendingFactor.ConstantColor; } throw new ArgumentException(nameof(BlendFactor) + " \"" + BlendFactor + "\" is not valid!"); } } }