Ryujinx/Ryujinx.Graphics.OpenGL/EnumConversion.cs
gdkchan 7aa430f1a5
Add support for advanced blend (part 1/2) (#2801)
* Add blend microcode registers

* Add advanced blend support using host extension

* Remove debug message

* Use pre-generated table for blend functions

* XML docs

* Rename AdvancedBlendMode to AdvancedBlendOp for consistency

* Remove redundant code

* Fix some advanced blend related issues on Vulkan

* Formatting
2023-02-19 22:37:37 -03:00

676 lines
27 KiB
C#

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
};
}
}
}