diff --git a/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs b/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
new file mode 100644
index 0000000000..1f1f7c3f15
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
@@ -0,0 +1,16 @@
+namespace Ryujinx.Graphics.GAL
+{
+    public struct AdvancedBlendDescriptor
+    {
+        public AdvancedBlendOp Op { get; }
+        public AdvancedBlendOverlap Overlap { get; }
+        public bool SrcPreMultiplied { get; }
+
+        public AdvancedBlendDescriptor(AdvancedBlendOp op, AdvancedBlendOverlap overlap, bool srcPreMultiplied)
+        {
+            Op = op;
+            Overlap = overlap;
+            SrcPreMultiplied = srcPreMultiplied;
+        }
+    }
+}
diff --git a/Ryujinx.Graphics.GAL/AdvancedBlendOp.cs b/Ryujinx.Graphics.GAL/AdvancedBlendOp.cs
new file mode 100644
index 0000000000..4140bf497a
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/AdvancedBlendOp.cs
@@ -0,0 +1,52 @@
+namespace Ryujinx.Graphics.GAL
+{
+    public enum AdvancedBlendOp
+    {
+        Zero,
+        Src,
+        Dst,
+        SrcOver,
+        DstOver,
+        SrcIn,
+        DstIn,
+        SrcOut,
+        DstOut,
+        SrcAtop,
+        DstAtop,
+        Xor,
+        Plus,
+        PlusClamped,
+        PlusClampedAlpha,
+        PlusDarker,
+        Multiply,
+        Screen,
+        Overlay,
+        Darken,
+        Lighten,
+        ColorDodge,
+        ColorBurn,
+        HardLight,
+        SoftLight,
+        Difference,
+        Minus,
+        MinusClamped,
+        Exclusion,
+        Contrast,
+        Invert,
+        InvertRGB,
+        InvertOvg,
+        LinearDodge,
+        LinearBurn,
+        VividLight,
+        LinearLight,
+        PinLight,
+        HardMix,
+        Red,
+        Green,
+        Blue,
+        HslHue,
+        HslSaturation,
+        HslColor,
+        HslLuminosity
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs b/Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs
new file mode 100644
index 0000000000..d4feb2b30e
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Graphics.GAL
+{
+    public enum AdvancedBlendOverlap
+    {
+        Uncorrelated,
+        Disjoint,
+        Conjoint
+    }
+}
diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index 7a1f44b6b0..a24139eba8 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.GAL
         public readonly bool SupportsR4G4B4A4Format;
         public readonly bool SupportsSnormBufferTextureFormat;
         public readonly bool Supports5BitComponentFormat;
+        public readonly bool SupportsBlendEquationAdvanced;
         public readonly bool SupportsFragmentShaderInterlock;
         public readonly bool SupportsFragmentShaderOrderingIntel;
         public readonly bool SupportsGeometryShaderPassthrough;
@@ -64,6 +65,7 @@ namespace Ryujinx.Graphics.GAL
             bool supportsR4G4B4A4Format,
             bool supportsSnormBufferTextureFormat,
             bool supports5BitComponentFormat,
+            bool supportsBlendEquationAdvanced,
             bool supportsFragmentShaderInterlock,
             bool supportsFragmentShaderOrderingIntel,
             bool supportsGeometryShaderPassthrough,
@@ -102,6 +104,7 @@ namespace Ryujinx.Graphics.GAL
             SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
             SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
             Supports5BitComponentFormat = supports5BitComponentFormat;
+            SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
             SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
             SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
             SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 26d019eb46..0a362081cb 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.GAL
 
         void SetAlphaTest(bool enable, float reference, CompareOp op);
 
+        void SetBlendState(AdvancedBlendDescriptor blend);
         void SetBlendState(int index, BlendDescriptor blend);
 
         void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);
diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
index 48873491fb..063b7edf9c 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
@@ -98,6 +98,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
             Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
             Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
             Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
+            Register<SetBlendStateAdvancedCommand>(CommandType.SetBlendStateAdvanced);
             Register<SetBlendStateCommand>(CommandType.SetBlendState);
             Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
             Register<SetDepthClampCommand>(CommandType.SetDepthClamp);
diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
index c199ff34c2..61e729b44c 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
@@ -60,6 +60,7 @@
         EndHostConditionalRendering,
         EndTransformFeedback,
         SetAlphaTest,
+        SetBlendStateAdvanced,
         SetBlendState,
         SetDepthBias,
         SetDepthClamp,
diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateAdvancedCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateAdvancedCommand.cs
new file mode 100644
index 0000000000..2ec10a5035
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateAdvancedCommand.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands
+{
+    struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand<SetBlendStateAdvancedCommand>
+    {
+        public CommandType CommandType => CommandType.SetBlendStateAdvanced;
+        private AdvancedBlendDescriptor _blend;
+
+        public void Set(AdvancedBlendDescriptor blend)
+        {
+            _blend = blend;
+        }
+
+        public static void Run(ref SetBlendStateAdvancedCommand command, ThreadedRenderer threaded, IRenderer renderer)
+        {
+            renderer.Pipeline.SetBlendState(command._blend);
+        }
+    }
+}
diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
index ba120867cc..1bdc9cf487 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
@@ -131,6 +131,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
             _renderer.QueueCommand();
         }
 
+        public void SetBlendState(AdvancedBlendDescriptor blend)
+        {
+            _renderer.New<SetBlendStateAdvancedCommand>().Set(blend);
+            _renderer.QueueCommand();
+        }
+
         public void SetBlendState(int index, BlendDescriptor blend)
         {
             _renderer.New<SetBlendStateCommand>().Set(index, blend);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs
new file mode 100644
index 0000000000..a40b9cc47e
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs
@@ -0,0 +1,4226 @@
+using Ryujinx.Common;
+using Ryujinx.Graphics.GAL;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
+{
+    static class AdvancedBlendFunctions
+    {
+        public static readonly AdvancedBlendUcode[] Table = new AdvancedBlendUcode[]
+        {
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusClamped,      AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedPlusClampedPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedPlusClampedAlphaPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusDarker,       AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedPlusDarkerPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedMultiplyPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedScreenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedOverlayPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedDarkenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedLightenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedColorDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedColorBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHardLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedSoftLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedDifferencePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Minus,            AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedMinusPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.MinusClamped,     AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedMinusClampedPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedExclusionPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Contrast,         AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedContrastPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Invert,           AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedInvertPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedInvertRGBPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertOvg,        AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedInvertOvgPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedLinearDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedLinearBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedVividLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedLinearLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedPinLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHardMixPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Red,              AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedRedPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Green,            AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedGreenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Blue,             AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedBluePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHslHuePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHslSaturationPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHslColorPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Uncorrelated, true,  GenUncorrelatedHslLuminosityPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Src,              AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSrcPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Dst,              AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDstPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOver,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSrcOverPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOver,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDstOverPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcIn,            AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSrcInPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstIn,            AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDstInPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOut,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSrcOutPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOut,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDstOutPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcAtop,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSrcAtopPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstAtop,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDstAtopPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Xor,              AdvancedBlendOverlap.Disjoint,     true,  GenDisjointXorPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Plus,             AdvancedBlendOverlap.Disjoint,     true,  GenDisjointPlusPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Disjoint,     true,  GenDisjointMultiplyPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointScreenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointOverlayPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDarkenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointLightenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Disjoint,     true,  GenDisjointColorDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Disjoint,     true,  GenDisjointColorBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHardLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Disjoint,     true,  GenDisjointSoftLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Disjoint,     true,  GenDisjointDifferencePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Disjoint,     true,  GenDisjointExclusionPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Invert,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointInvertPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Disjoint,     true,  GenDisjointInvertRGBPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Disjoint,     true,  GenDisjointLinearDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Disjoint,     true,  GenDisjointLinearBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Disjoint,     true,  GenDisjointVividLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Disjoint,     true,  GenDisjointLinearLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Disjoint,     true,  GenDisjointPinLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHardMixPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHslHuePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHslSaturationPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHslColorPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Disjoint,     true,  GenDisjointHslLuminosityPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Src,              AdvancedBlendOverlap.Conjoint,     true,  GenConjointSrcPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Dst,              AdvancedBlendOverlap.Conjoint,     true,  GenConjointDstPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOver,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointSrcOverPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOver,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointDstOverPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcIn,            AdvancedBlendOverlap.Conjoint,     true,  GenConjointSrcInPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstIn,            AdvancedBlendOverlap.Conjoint,     true,  GenConjointDstInPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOut,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointSrcOutPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOut,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointDstOutPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcAtop,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointSrcAtopPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstAtop,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointDstAtopPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Xor,              AdvancedBlendOverlap.Conjoint,     true,  GenConjointXorPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Conjoint,     true,  GenConjointMultiplyPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointScreenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointOverlayPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointDarkenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointLightenPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Conjoint,     true,  GenConjointColorDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Conjoint,     true,  GenConjointColorBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Conjoint,     true,  GenConjointHardLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Conjoint,     true,  GenConjointSoftLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Conjoint,     true,  GenConjointDifferencePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Conjoint,     true,  GenConjointExclusionPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.Invert,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointInvertPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Conjoint,     true,  GenConjointInvertRGBPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Conjoint,     true,  GenConjointLinearDodgePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Conjoint,     true,  GenConjointLinearBurnPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Conjoint,     true,  GenConjointVividLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Conjoint,     true,  GenConjointLinearLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Conjoint,     true,  GenConjointPinLightPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Conjoint,     true,  GenConjointHardMixPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Conjoint,     true,  GenConjointHslHuePremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Conjoint,     true,  GenConjointHslSaturationPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Conjoint,     true,  GenConjointHslColorPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Conjoint,     true,  GenConjointHslLuminosityPremul),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOver,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedDstOver),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcIn,            AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedSrcIn),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOut,           AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedSrcOut),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcAtop,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedSrcAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstAtop,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedDstAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.Xor,              AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedXor),
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusClamped,      AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedPlusClamped),
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedPlusClampedAlpha),
+            new AdvancedBlendUcode(AdvancedBlendOp.PlusDarker,       AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedPlusDarker),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedMultiply),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedScreen),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedOverlay),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedDarken),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedLighten),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedColorDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedColorBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHardLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedSoftLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedDifference),
+            new AdvancedBlendUcode(AdvancedBlendOp.Minus,            AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedMinus),
+            new AdvancedBlendUcode(AdvancedBlendOp.MinusClamped,     AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedMinusClamped),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedExclusion),
+            new AdvancedBlendUcode(AdvancedBlendOp.Contrast,         AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedContrast),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedInvertRGB),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedLinearDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedLinearBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedVividLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedLinearLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedPinLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHardMix),
+            new AdvancedBlendUcode(AdvancedBlendOp.Red,              AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedRed),
+            new AdvancedBlendUcode(AdvancedBlendOp.Green,            AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedGreen),
+            new AdvancedBlendUcode(AdvancedBlendOp.Blue,             AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedBlue),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHslHue),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHslSaturation),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHslColor),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Uncorrelated, false, GenUncorrelatedHslLuminosity),
+            new AdvancedBlendUcode(AdvancedBlendOp.Src,              AdvancedBlendOverlap.Disjoint,     false, GenDisjointSrc),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOver,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointSrcOver),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOver,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointDstOver),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcIn,            AdvancedBlendOverlap.Disjoint,     false, GenDisjointSrcIn),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOut,           AdvancedBlendOverlap.Disjoint,     false, GenDisjointSrcOut),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcAtop,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointSrcAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstAtop,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointDstAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.Xor,              AdvancedBlendOverlap.Disjoint,     false, GenDisjointXor),
+            new AdvancedBlendUcode(AdvancedBlendOp.Plus,             AdvancedBlendOverlap.Disjoint,     false, GenDisjointPlus),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Disjoint,     false, GenDisjointMultiply),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Disjoint,     false, GenDisjointScreen),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointOverlay),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Disjoint,     false, GenDisjointDarken),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointLighten),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Disjoint,     false, GenDisjointColorDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Disjoint,     false, GenDisjointColorBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Disjoint,     false, GenDisjointHardLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Disjoint,     false, GenDisjointSoftLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Disjoint,     false, GenDisjointDifference),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Disjoint,     false, GenDisjointExclusion),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Disjoint,     false, GenDisjointInvertRGB),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Disjoint,     false, GenDisjointLinearDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Disjoint,     false, GenDisjointLinearBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Disjoint,     false, GenDisjointVividLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Disjoint,     false, GenDisjointLinearLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Disjoint,     false, GenDisjointPinLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Disjoint,     false, GenDisjointHardMix),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Disjoint,     false, GenDisjointHslHue),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Disjoint,     false, GenDisjointHslSaturation),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Disjoint,     false, GenDisjointHslColor),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Disjoint,     false, GenDisjointHslLuminosity),
+            new AdvancedBlendUcode(AdvancedBlendOp.Src,              AdvancedBlendOverlap.Conjoint,     false, GenConjointSrc),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOver,          AdvancedBlendOverlap.Conjoint,     false, GenConjointSrcOver),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstOver,          AdvancedBlendOverlap.Conjoint,     false, GenConjointDstOver),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcIn,            AdvancedBlendOverlap.Conjoint,     false, GenConjointSrcIn),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcOut,           AdvancedBlendOverlap.Conjoint,     false, GenConjointSrcOut),
+            new AdvancedBlendUcode(AdvancedBlendOp.SrcAtop,          AdvancedBlendOverlap.Conjoint,     false, GenConjointSrcAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.DstAtop,          AdvancedBlendOverlap.Conjoint,     false, GenConjointDstAtop),
+            new AdvancedBlendUcode(AdvancedBlendOp.Xor,              AdvancedBlendOverlap.Conjoint,     false, GenConjointXor),
+            new AdvancedBlendUcode(AdvancedBlendOp.Multiply,         AdvancedBlendOverlap.Conjoint,     false, GenConjointMultiply),
+            new AdvancedBlendUcode(AdvancedBlendOp.Screen,           AdvancedBlendOverlap.Conjoint,     false, GenConjointScreen),
+            new AdvancedBlendUcode(AdvancedBlendOp.Overlay,          AdvancedBlendOverlap.Conjoint,     false, GenConjointOverlay),
+            new AdvancedBlendUcode(AdvancedBlendOp.Darken,           AdvancedBlendOverlap.Conjoint,     false, GenConjointDarken),
+            new AdvancedBlendUcode(AdvancedBlendOp.Lighten,          AdvancedBlendOverlap.Conjoint,     false, GenConjointLighten),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorDodge,       AdvancedBlendOverlap.Conjoint,     false, GenConjointColorDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.ColorBurn,        AdvancedBlendOverlap.Conjoint,     false, GenConjointColorBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardLight,        AdvancedBlendOverlap.Conjoint,     false, GenConjointHardLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.SoftLight,        AdvancedBlendOverlap.Conjoint,     false, GenConjointSoftLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.Difference,       AdvancedBlendOverlap.Conjoint,     false, GenConjointDifference),
+            new AdvancedBlendUcode(AdvancedBlendOp.Exclusion,        AdvancedBlendOverlap.Conjoint,     false, GenConjointExclusion),
+            new AdvancedBlendUcode(AdvancedBlendOp.InvertRGB,        AdvancedBlendOverlap.Conjoint,     false, GenConjointInvertRGB),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearDodge,      AdvancedBlendOverlap.Conjoint,     false, GenConjointLinearDodge),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearBurn,       AdvancedBlendOverlap.Conjoint,     false, GenConjointLinearBurn),
+            new AdvancedBlendUcode(AdvancedBlendOp.VividLight,       AdvancedBlendOverlap.Conjoint,     false, GenConjointVividLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.LinearLight,      AdvancedBlendOverlap.Conjoint,     false, GenConjointLinearLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.PinLight,         AdvancedBlendOverlap.Conjoint,     false, GenConjointPinLight),
+            new AdvancedBlendUcode(AdvancedBlendOp.HardMix,          AdvancedBlendOverlap.Conjoint,     false, GenConjointHardMix),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslHue,           AdvancedBlendOverlap.Conjoint,     false, GenConjointHslHue),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslSaturation,    AdvancedBlendOverlap.Conjoint,     false, GenConjointHslSaturation),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslColor,         AdvancedBlendOverlap.Conjoint,     false, GenConjointHslColor),
+            new AdvancedBlendUcode(AdvancedBlendOp.HslLuminosity,    AdvancedBlendOverlap.Conjoint,     false, GenConjointHslLuminosity)
+        };
+
+        public static string GenTable()
+        {
+            // This can be used to generate the table on AdvancedBlendPreGenTable.
+
+            StringBuilder sb = new StringBuilder();
+
+            sb.AppendLine($"private static Dictionary<Hash128, AdvancedBlendEntry> _entries = new()");
+            sb.AppendLine("{");
+
+            foreach (var entry in Table)
+            {
+                Hash128 hash = XXHash128.ComputeHash(MemoryMarshal.Cast<uint, byte>(entry.Code));
+
+                string[] constants = new string[entry.Constants != null ? entry.Constants.Length : 0];
+
+                for (int i = 0; i < constants.Length; i++)
+                {
+                    RgbFloat rgb = entry.Constants[i];
+
+                    constants[i] = string.Format(CultureInfo.InvariantCulture, "new " + nameof(RgbFloat) + "({0}f, {1}f, {2}f)", rgb.R, rgb.G, rgb.B);
+                }
+
+                string constantList = constants.Length > 0 ? $"new[] {{ {string.Join(", ", constants)} }}" : $"Array.Empty<{nameof(RgbFloat)}>()";
+
+                static string EnumValue(string name, object value)
+                {
+                    if (value.ToString() == "0")
+                    {
+                        return "0";
+                    }
+
+                    return $"{name}.{value}";
+                }
+
+                string alpha = $"new {nameof(FixedFunctionAlpha)}({EnumValue(nameof(BlendUcodeEnable), entry.Alpha.Enable)}, {EnumValue(nameof(BlendOp), entry.Alpha.AlphaOp)}, {EnumValue(nameof(BlendFactor), entry.Alpha.AlphaSrcFactor)}, {EnumValue(nameof(BlendFactor), entry.Alpha.AlphaDstFactor)})";
+
+                sb.AppendLine($"    {{ new Hash128(0x{hash.Low:X16}, 0x{hash.High:X16}), new AdvancedBlendEntry({nameof(AdvancedBlendOp)}.{entry.Op}, {nameof(AdvancedBlendOverlap)}.{entry.Overlap}, {(entry.SrcPreMultiplied ? "true" : "false")}, {constantList}, {alpha}) }},");
+            }
+
+            sb.AppendLine("};");
+
+            return sb.ToString();
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusClampedPremul(ref UcodeAssembler asm)
+        {
+            asm.Add(CC.T, Dest.PBR, OpBD.DstRGB, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusClampedAlphaPremul(ref UcodeAssembler asm)
+        {
+            asm.Add(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.SrcRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusDarkerPremul(ref UcodeAssembler asm)
+        {
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.SrcRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstRGB);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.SrcAAA);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMultiplyPremul(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedScreenPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedOverlayPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDarkenPremul(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLightenPremul(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedColorDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.SrcRGB);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.SrcAAA);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.DstRGB);
+            asm.Min(CC.GT, Dest.PBR, OpAC.DstAAA, OpBD.PBR);
+            asm.Mul(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.SrcAAA);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.DstRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedColorBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.DstAAA, OpBD.SrcAAA, OpAC.SrcAAA, OpBD.DstRGB);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcRGB);
+            asm.Mul(CC.T, Dest.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA, OpAC.SrcAAA, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.DstAAA, OpBD.DstRGB);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHardLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedSoftLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDifferencePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.Temp2, OpBD.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMinusPremul(ref UcodeAssembler asm)
+        {
+            asm.Sub(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.SrcRGB);
+            return new FixedFunctionAlpha(BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMinusClampedPremul(ref UcodeAssembler asm)
+        {
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstRGB, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedExclusionPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.DstRGB);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedContrastPremul(ref UcodeAssembler asm)
+        {
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.ConstantRGB, OpAC.DstAAA, OpBD.ConstantOne);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.SrcAAA, OpBD.ConstantOne);
+            asm.Mul(CC.T, Dest.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstAAA);
+            asm.SetConstant(1, 0.5f, 0.5f, 0.5f);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedInvertPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA, OpAC.SrcAAA, OpBD.DstRGB);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.OneMinusSrcAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedInvertRGBPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.DstAAA, OpAC.SrcRGB, OpBD.DstRGB);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.OneMinusSrcAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedInvertOvgPremul(ref UcodeAssembler asm)
+        {
+            asm.Sub(CC.T, Dest.PBR, OpBD.ConstantOne, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.Temp0, OpAC.SrcAAA, OpBD.PBR, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Mmadd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedVividLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPinLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHardMixPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedRedPremul(ref UcodeAssembler asm)
+        {
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.R, OpBD.SrcRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedGreenPremul(ref UcodeAssembler asm)
+        {
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.G, OpBD.SrcRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedBluePremul(ref UcodeAssembler asm)
+        {
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.B, OpBD.SrcRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslHuePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp2, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslSaturationPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslColorPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp2, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslLuminosityPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.SrcRGB, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.Temp1, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcOverPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp2);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstOverPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp1);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcInPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Sub(CC.T, Dest.Temp1.RToA, OpBD.DstAAA, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstInPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.Temp1, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Sub(CC.T, Dest.Temp1.RToA, OpBD.DstAAA, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcOutPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstOutPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcAtopPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstAtopPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.Temp1, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointXorPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            asm.Min(CC.T, Dest.Temp1, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Add(CC.T, Dest.Temp1.RToA, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointPlusPremul(ref UcodeAssembler asm)
+        {
+            asm.Add(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.SrcRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointMultiplyPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointScreenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointOverlayPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDarkenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLightenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointColorDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp0);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp1, OpBD.ConstantZero);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointColorBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp2);
+            asm.Mmsub(CC.GT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHardLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSoftLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDifferencePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.Temp2, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointExclusionPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointInvertPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp0, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointInvertRGBPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.ConstantOne, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp0, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointVividLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointPinLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHardMixPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslHuePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp2, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslSaturationPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslColorPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp2, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslLuminosityPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.Temp2, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcOverPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp2, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstOverPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcInPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstInPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcOutPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointDstOutPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcAtopPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstAtopPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointXorPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            asm.Sub(CC.T, Dest.Temp1.CC, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Sub(CC.LT, Dest.Temp1, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mov(CC.T, Dest.Temp1.RToA, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointMultiplyPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointScreenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointOverlayPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDarkenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLightenPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointColorDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp0);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp1, OpBD.ConstantZero);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointColorBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp2);
+            asm.Mmsub(CC.GT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHardLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp2, OpBD.Temp1, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSoftLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDifferencePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.Temp2, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointExclusionPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointInvertPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointInvertRGBPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.ConstantOne, OpAC.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearDodgePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearBurnPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointVividLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.Temp2);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointPinLightPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.Temp2, OpBD.Temp2);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHardMixPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslHuePremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp2, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslSaturationPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslColorPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp2, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslLuminosityPremul(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp2, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.Temp2, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.PBR);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp2, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDstOver(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedSrcIn(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.DstAlphaGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedSrcOut(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.OneMinusDstAAA);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedSrcAtop(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.OneMinusSrcAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDstAtop(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedXor(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.PBR, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.OneMinusSrcAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusClamped(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Add(CC.T, Dest.PBR, OpBD.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusClampedAlpha(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPlusDarker(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstRGB);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.SrcAAA);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMultiply(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedScreen(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedOverlay(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDarken(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLighten(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedColorDodge(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.PBR);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.SrcAAA);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.DstRGB);
+            asm.Min(CC.GT, Dest.PBR, OpAC.DstAAA, OpBD.PBR);
+            asm.Mul(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.SrcAAA);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.DstRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedColorBurn(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.DstAAA, OpBD.SrcAAA, OpAC.SrcAAA, OpBD.DstRGB);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.Temp2);
+            asm.Mul(CC.T, Dest.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA, OpAC.SrcAAA, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp2, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.DstAAA, OpBD.DstRGB);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHardLight(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedSoftLight(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedDifference(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.SrcRGB, OpBD.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMinus(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedMinusClamped(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstRGB, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedExclusion(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.DstRGB);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.Temp2, OpBD.DstRGB);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedContrast(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.ConstantRGB, OpAC.DstAAA, OpBD.ConstantOne);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.Temp2, OpBD.ConstantRGB, OpAC.SrcAAA, OpBD.ConstantOne);
+            asm.Mul(CC.T, Dest.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.PBR, OpBD.DstAAA);
+            asm.SetConstant(1, 0.5f, 0.5f, 0.5f);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantRGB);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedInvertRGB(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA, OpAC.PBR, OpBD.DstRGB);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.DstRGB, OpBD.OneMinusSrcAAA, OpAC.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearDodge(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearBurn(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.PBR, OpBD.DstAAA, OpAC.DstRGB, OpBD.SrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mmadd(CC.T, Dest.PBR, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.Temp0, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedVividLight(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedLinearLight(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedPinLight(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHardMix(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.Temp2, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedRed(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.R, OpBD.Temp2);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedGreen(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.G, OpBD.Temp2);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedBlue(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.Temp2, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.DstRGB);
+            asm.Mov(CC.T, Dest.Temp0.B, OpBD.Temp2);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslHue(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.SrcRGB, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.PBR, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslSaturation(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.PBR, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslColor(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.PBR, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenUncorrelatedHslLuminosity(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Mmadd(CC.T, Dest.Temp1, OpAC.PBR, OpBD.OneMinusDstAAA, OpAC.DstRGB, OpBD.OneMinusSrcAAA);
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.DstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrc(ref UcodeAssembler asm)
+        {
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcOver(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.SrcRGB);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstOver(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp1);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcIn(ref UcodeAssembler asm)
+        {
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Sub(CC.T, Dest.Temp1.RToA, OpBD.DstAAA, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcOut(ref UcodeAssembler asm)
+        {
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSrcAtop(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointDstAtop(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.Temp1, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointXor(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            asm.Min(CC.T, Dest.Temp1, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Add(CC.T, Dest.Temp1.RToA, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointPlus(ref UcodeAssembler asm)
+        {
+            asm.Mul(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.SrcAAA);
+            asm.Add(CC.T, Dest.Temp0, OpBD.DstRGB, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointMultiply(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointScreen(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointOverlay(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDarken(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLighten(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointColorDodge(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp0);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp1, OpBD.ConstantZero);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointColorBurn(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHardLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointSoftLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointDifference(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.SrcRGB, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointExclusion(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointInvertRGB(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.Temp0, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearDodge(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearBurn(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointVividLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointLinearLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointPinLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHardMix(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslHue(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.SrcRGB, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslSaturation(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslColor(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenDisjointHslLuminosity(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.OneMinusSrcAAA);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.Temp1, OpAC.PBR, OpBD.Temp0);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.SrcAAA, OpBD.OneMinusDstAAA);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.PBR, OpBD.SrcRGB, OpAC.Temp0);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Min(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointSrc(ref UcodeAssembler asm)
+        {
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcOver(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.SrcRGB, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstOver(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp1, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcIn(ref UcodeAssembler asm)
+        {
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcOut(ref UcodeAssembler asm)
+        {
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.Temp1.RToA, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointSrcAtop(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDstAtop(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointXor(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            asm.Sub(CC.T, Dest.Temp1.CC, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Sub(CC.LT, Dest.Temp1, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mov(CC.T, Dest.Temp1.RToA, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.Temp0);
+            return FixedFunctionAlpha.Disabled;
+        }
+
+        private static FixedFunctionAlpha GenConjointMultiply(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointScreen(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointOverlay(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDarken(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLighten(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointColorDodge(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.Temp0);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.Temp1, OpBD.ConstantZero);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointColorBurn(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Max(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Mov(CC.LE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHardLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.SrcRGB, OpBD.Temp1, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.GT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointSoftLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(4, 0.25f, 0.25f, 0.25f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(0, 0.2605f, 0.2605f, 0.2605f);
+            asm.Mul(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(1, -0.7817f, -0.7817f, -0.7817f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(2, 0.3022f, 0.3022f, 0.3022f);
+            asm.Mmadd(CC.GT, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(3, 0.2192f, 0.2192f, 0.2192f);
+            asm.Add(CC.GT, Dest.Temp0, OpBD.PBR, OpBD.ConstantRGB);
+            asm.SetConstant(5, 16f, 16f, 16f);
+            asm.Mul(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(6, 12f, 12f, 12f);
+            asm.Mmsub(CC.LE, Dest.PBR, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.SetConstant(7, 3f, 3f, 3f);
+            asm.Mmadd(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mmsub(CC.LE, Dest.Temp0, OpAC.Temp1, OpBD.ConstantOne, OpAC.Temp1, OpBD.Temp1);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointDifference(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointExclusion(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointInvertRGB(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mmsub(CC.T, Dest.Temp0, OpAC.SrcRGB, OpBD.ConstantOne, OpAC.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR, OpAC.DstAAA, OpBD.SrcAAA);
+            asm.Mul(CC.T, Dest.Temp0, OpAC.Temp0, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Madd(CC.T, Dest.Temp0, OpAC.Temp1, OpBD.PBR, OpAC.Temp0);
+            return new FixedFunctionAlpha(BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearDodge(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearBurn(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointVividLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.5f, 0.5f, 0.5f);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantRGB);
+            asm.Sub(CC.GE, Dest.PBR, OpBD.ConstantOne, OpBD.SrcRGB);
+            asm.Add(CC.GE, Dest.PBR, OpBD.PBR, OpBD.PBR);
+            asm.Rcp(CC.GE, Dest.PBR, OpAC.PBR);
+            asm.Mul(CC.GE, Dest.PBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GE, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Add(CC.LT, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Rcp(CC.LT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.LT, Dest.PBR, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.LT, Dest.Temp0, OpBD.ConstantOne, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantZero);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcRGB, OpBD.ConstantOne);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointLinearLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 2f, 2f, 2f);
+            asm.Madd(CC.T, Dest.PBR, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Max(CC.T, Dest.PBR, OpAC.PBR, OpBD.ConstantZero);
+            asm.Min(CC.T, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointPinLight(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.ConstantZero);
+            asm.Add(CC.LE, Dest.PBR, OpBD.SrcRGB, OpBD.SrcRGB);
+            asm.Min(CC.LE, Dest.Temp0, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHardMix(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Add(CC.T, Dest.PBR, OpBD.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Mul(CC.LT, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Mov(CC.GE, Dest.Temp0, OpBD.ConstantOne);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslHue(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.SrcRGB, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.Temp2.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp2);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslSaturation(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.PBR);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.Temp0.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.Temp0.CC, OpBD.PBR, OpBD.Temp0);
+            asm.Rcp(CC.GT, Dest.Temp0, OpAC.Temp0);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.Temp1, OpAC.Temp0, OpBD.PBR);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Min(CC.GT, Dest.Temp1.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mov(CC.GT, Dest.PBR.GBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Max(CC.GT, Dest.PBR.GBR, OpAC.PBR, OpBD.SrcRGB);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp0, OpBD.Temp1);
+            asm.Mul(CC.LE, Dest.Temp0, OpAC.SrcAAA, OpBD.ConstantZero);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp0, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp0, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslColor(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.PBR, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp1.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp2, OpBD.SrcRGB, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp1);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp2, OpBD.Temp1);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp1);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp2);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp1, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp2, OpBD.Temp1, OpAC.Temp1, OpBD.Temp1);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp1);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+
+        private static FixedFunctionAlpha GenConjointHslLuminosity(ref UcodeAssembler asm)
+        {
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.SetConstant(0, 0.3f, 0.59f, 0.11f);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.SrcRGB, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.Temp2.BBB, OpAC.SrcRGB, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Mul(CC.T, Dest.PBR.RRR, OpAC.Temp1, OpBD.ConstantRGB);
+            asm.Madd(CC.T, Dest.PBR.GGG, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Madd(CC.T, Dest.PBR.BBB, OpAC.Temp1, OpBD.ConstantRGB, OpAC.PBR);
+            asm.Sub(CC.T, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Add(CC.T, Dest.Temp1, OpBD.Temp1, OpBD.PBR);
+            asm.Mov(CC.T, Dest.Temp0, OpBD.PBR);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Max(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.PBR, OpBD.ConstantOne);
+            asm.Add(CC.GT, Dest.PBR, OpBD.PBR, OpBD.ConstantOne);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.PBR, OpBD.Temp2);
+            asm.Rcp(CC.GT, Dest.PBR, OpAC.PBR);
+            asm.Mmsub(CC.GT, Dest.Temp0, OpAC.PBR, OpBD.ConstantOne, OpAC.PBR, OpBD.Temp2);
+            asm.Sub(CC.GT, Dest.PBR, OpBD.Temp1, OpBD.Temp2);
+            asm.Madd(CC.GT, Dest.Temp0, OpAC.Temp0, OpBD.PBR, OpAC.Temp2);
+            asm.Mov(CC.T, Dest.PBR.GBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR, OpAC.PBR, OpBD.Temp1);
+            asm.Min(CC.T, Dest.PBR.GBR.CC, OpAC.PBR, OpBD.Temp1);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.Temp2, OpBD.PBR);
+            asm.Rcp(CC.LT, Dest.Temp0, OpAC.PBR);
+            asm.Mmsub(CC.LT, Dest.PBR, OpAC.Temp1, OpBD.Temp2, OpAC.Temp2, OpBD.Temp2);
+            asm.Madd(CC.LT, Dest.Temp0, OpAC.PBR, OpBD.Temp0, OpAC.Temp2);
+            asm.Rcp(CC.T, Dest.PBR, OpAC.DstAAA);
+            asm.Mul(CC.T, Dest.Temp1, OpAC.DstRGB, OpBD.PBR);
+            asm.Sub(CC.T, Dest.PBR.CC, OpBD.SrcAAA, OpBD.DstAAA);
+            asm.Mmadd(CC.GE, Dest.Temp0, OpAC.Temp0, OpBD.DstAAA, OpAC.SrcRGB, OpBD.PBR);
+            asm.Sub(CC.LT, Dest.PBR, OpBD.DstAAA, OpBD.SrcAAA);
+            asm.Mmadd(CC.LT, Dest.Temp0, OpAC.Temp0, OpBD.SrcAAA, OpAC.Temp1, OpBD.PBR);
+            return new FixedFunctionAlpha(BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendManager.cs
new file mode 100644
index 0000000000..8072c6af28
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendManager.cs
@@ -0,0 +1,115 @@
+using Ryujinx.Common;
+using Ryujinx.Graphics.GAL;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
+{
+    /// <summary>
+    /// Advanced blend manager.
+    /// </summary>
+    class AdvancedBlendManager
+    {
+        private const int InstructionRamSize = 128;
+        private const int InstructionRamSizeMask = InstructionRamSize - 1;
+
+        private readonly DeviceStateWithShadow<ThreedClassState> _state;
+
+        private readonly uint[] _code;
+        private int _ip;
+
+        /// <summary>
+        /// Creates a new instance of the advanced blend manager.
+        /// </summary>
+        /// <param name="state">GPU state of the channel owning this manager</param>
+        public AdvancedBlendManager(DeviceStateWithShadow<ThreedClassState> state)
+        {
+            _state = state;
+            _code = new uint[InstructionRamSize];
+        }
+
+        /// <summary>
+        /// Sets the start offset of the blend microcode in memory.
+        /// </summary>
+        /// <param name="argument">Method call argument</param>
+        public void LoadBlendUcodeStart(int argument)
+        {
+            _ip = argument;
+        }
+
+        /// <summary>
+        /// Pushes one word of blend microcode.
+        /// </summary>
+        /// <param name="argument">Method call argument</param>
+        public void LoadBlendUcodeInstruction(int argument)
+        {
+            _code[_ip++ & InstructionRamSizeMask] = (uint)argument;
+        }
+
+        /// <summary>
+        /// Tries to identify the current advanced blend function being used,
+        /// given the current state and microcode that was uploaded.
+        /// </summary>
+        /// <param name="descriptor">Advanced blend descriptor</param>
+        /// <returns>True if the function was found, false otherwise</returns>
+        public bool TryGetAdvancedBlend(out AdvancedBlendDescriptor descriptor)
+        {
+            Span<uint> currentCode = new Span<uint>(_code);
+            byte codeLength = (byte)_state.State.BlendUcodeSize;
+
+            if (currentCode.Length > codeLength)
+            {
+                currentCode = currentCode.Slice(0, codeLength);
+            }
+
+            Hash128 hash = XXHash128.ComputeHash(MemoryMarshal.Cast<uint, byte>(currentCode));
+
+            descriptor = default;
+
+            if (!AdvancedBlendPreGenTable.Entries.TryGetValue(hash, out var entry))
+            {
+                return false;
+            }
+
+            if (entry.Constants != null)
+            {
+                bool constantsMatch = true;
+
+                for (int i = 0; i < entry.Constants.Length; i++)
+                {
+                    RgbFloat constant = entry.Constants[i];
+                    RgbHalf constant2 = _state.State.BlendUcodeConstants[i];
+
+                    if ((Half)constant.R != constant2.UnpackR() ||
+                        (Half)constant.G != constant2.UnpackG() ||
+                        (Half)constant.B != constant2.UnpackB())
+                    {
+                        constantsMatch = false;
+                        break;
+                    }
+                }
+
+                if (!constantsMatch)
+                {
+                    return false;
+                }
+            }
+
+            if (entry.Alpha.Enable != _state.State.BlendUcodeEnable)
+            {
+                return false;
+            }
+
+            if (entry.Alpha.Enable == BlendUcodeEnable.EnableRGBA &&
+                (entry.Alpha.AlphaOp != _state.State.BlendStateCommon.AlphaOp ||
+                entry.Alpha.AlphaSrcFactor != _state.State.BlendStateCommon.AlphaSrcFactor ||
+                entry.Alpha.AlphaDstFactor != _state.State.BlendStateCommon.AlphaDstFactor))
+            {
+                return false;
+            }
+
+            descriptor = new AdvancedBlendDescriptor(entry.Op, entry.Overlap, entry.SrcPreMultiplied);
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs
new file mode 100644
index 0000000000..d35d8abf4b
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs
@@ -0,0 +1,273 @@
+using Ryujinx.Common;
+using Ryujinx.Graphics.GAL;
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
+{
+    /// <summary>
+    /// Advanced blend function entry.
+    /// </summary>
+    struct AdvancedBlendEntry
+    {
+        /// <summary>
+        /// Advanced blend operation.
+        /// </summary>
+        public AdvancedBlendOp Op { get; }
+
+        /// <summary>
+        /// Advanced blend overlap mode.
+        /// </summary>
+        public AdvancedBlendOverlap Overlap { get; }
+
+        /// <summary>
+        /// Whenever the source input is pre-multiplied.
+        /// </summary>
+        public bool SrcPreMultiplied { get; }
+
+        /// <summary>
+        /// Constants used by the microcode.
+        /// </summary>
+        public RgbFloat[] Constants { get; }
+
+        /// <summary>
+        /// Fixed function alpha state.
+        /// </summary>
+        public FixedFunctionAlpha Alpha { get; }
+
+        /// <summary>
+        /// Creates a new advanced blend function entry.
+        /// </summary>
+        /// <param name="op">Advanced blend operation</param>
+        /// <param name="overlap">Advanced blend overlap mode</param>
+        /// <param name="srcPreMultiplied">Whenever the source input is pre-multiplied</param>
+        /// <param name="constants">Constants used by the microcode</param>
+        /// <param name="alpha">Fixed function alpha state</param>
+        public AdvancedBlendEntry(
+            AdvancedBlendOp op,
+            AdvancedBlendOverlap overlap,
+            bool srcPreMultiplied,
+            RgbFloat[] constants,
+            FixedFunctionAlpha alpha)
+        {
+            Op = op;
+            Overlap = overlap;
+            SrcPreMultiplied = srcPreMultiplied;
+            Constants = constants;
+            Alpha = alpha;
+        }
+    }
+
+    /// <summary>
+    /// Pre-generated hash table with advanced blend functions used by the driver.
+    /// </summary>
+    static class AdvancedBlendPreGenTable
+    {
+        /// <summary>
+        /// Advanced blend functions dictionary.
+        /// </summary>
+        public static readonly IReadOnlyDictionary<Hash128, AdvancedBlendEntry> Entries = new Dictionary<Hash128, AdvancedBlendEntry>()
+        {
+            { new Hash128(0x19ECF57B83DE31F7, 0x5BAE759246F264C0), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xDE1B14A356A1A9ED, 0x59D803593C607C1D), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x1A3C3A6D32DEC368, 0xBCAE519EC6AAA045), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x6FD380261A63B240, 0x17C3B335DBB9E3DB), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x1D39164823D3A2D1, 0xC45350959CE1C8FB), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x18DF09FF53B129FE, 0xC02EDA33C36019F6), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x5973E583271EBF06, 0x711497D75D1272E0), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x4759E0E5DA54D5E8, 0x1FDD57C0C38AFA1F), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x337684D43CCE97FA, 0x0139E30CC529E1C9), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xDA59E85D8428992D, 0x1D3D7C64C9EF0132), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x9455B949298CE805, 0xE73D3301518BE98A), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xBDD3B4DEDBE336AA, 0xBFA4DCD50D535DEE), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x22D4E970A028649A, 0x4F3FCB055FCED965), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xA346A91311D72114, 0x151A27A3FB0A1904), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x8A307241061FACD6, 0xA39D1826440B8EE7), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xB3BE569485EFFFE0, 0x0BA4E269B3CFB165), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x36FCA3277DC11822, 0x2BC0F6CAC2029672), new AdvancedBlendEntry(AdvancedBlendOp.Contrast, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(2f, 2f, 2f), new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x4A6226AF2DE9BD7F, 0xEB890D7DA716F73A), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0xF364CAA94E160FEB, 0xBF364512C72A3797), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x6BF791AB4AC19C87, 0x6FA17A994EA0FCDE), new AdvancedBlendEntry(AdvancedBlendOp.InvertOvg, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x053C75A0AE0BB222, 0x03C791FEEB59754C), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x25762AB40B6CBDE9, 0x595E9A968AC4F01C), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xC2D05E2DBE16955D, 0xB8659C7A3FCFA7CE), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x223F220B8F74CBFB, 0xD3DD19D7C39209A5), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xD0DAE57A9F1FE78A, 0x353796BCFB8CE30B), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x601C8CBEC07FF8FF, 0xB8E22882360E8695), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x3A55B7B78C76A7A8, 0x206F503B2D9FFEAA), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x80BC65C7831388E5, 0xC652457B2C766AEC), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x3D3A912E5833EE13, 0x307895951349EE33), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x289105BE92E81803, 0xFD8F1F03D15C53B4), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x007AE3BD140764EB, 0x0EE05A0D2E80BBAE), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x77F7EE0DB3FDDB96, 0xDEA47C881306DB3E), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x66F4E9A7D73CA157, 0x1486058A177DB11C), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x593E9F331612D618, 0x9D217BEFA4EB919A), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x0A5194C5E6891106, 0xDD8EC6586106557C), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x8D77173D5E06E916, 0x06AB190E7D10F4D4), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x655B4EBC148981DA, 0x455999EF2B9BD28A), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x98F5437D5F518929, 0xBFF4A6E83183DB63), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x6ADDEFE3B9CEF2FD, 0xB6F6272AFECB1AAB), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x80953F0953BF05B1, 0xD59ABFAA34F8196F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xA401D9AA2A39C121, 0xFC0C8005C22AD7E3), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x06274FB7CA9CDD22, 0x6CE8188B1A9AB6EF), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x0B079BE7F7F70817, 0xB72E7736CA51E321), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x66215C99403CEDDE, 0x900B733D62204C48), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x12DEF2AD900CAD6C, 0x58CF5CC3004910DF), new AdvancedBlendEntry(AdvancedBlendOp.Plus, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x272BA3A49F64DAE4, 0xAC70B96C00A99EAF), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x206C34AAA7D3F545, 0xDA4B30CACAA483A0), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x3D93494920D257BE, 0xDCC573BE1F5F4449), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x0D7417D80191107B, 0xEAF40547827E005F), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xEC1B03E8C883F9C9, 0x2D3CA044C58C01B4), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x58A19A0135D68B31, 0x82F35B97AED068E5), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x20489F9AB36CC0E3, 0x20499874219E35EE), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xBB176935E5EE05BF, 0x95B26D4D30EA7A14), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x5FF9393C908ACFED, 0x068B0BD875773ABF), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x03181F8711C9802C, 0x6B02C7C6B224FE7B), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x2EE2209021F6B977, 0xF3AFA1491B8B89FC), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xD8BA4DD2EDE4DC9E, 0x01006114977CF715), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0xD156B99835A2D8ED, 0x2D0BEE9E135EA7A7), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x20CE8C898ED4BE27, 0x1514900B6F5E8F66), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xCDE5F743820BA2D9, 0x917845FE2ECB083D), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xEB03DF4A0C1D14CD, 0xBAE2E831C6E8FFE4), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x1DC9E49AABC779AC, 0x4053A1441EB713D3), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xFBDEF776248F7B3E, 0xE05EEFD65AC47CB7), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x415A1A48E03AA6E7, 0x046D7EE33CA46B9A), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x59A6901EC9BB2041, 0x2F3E19CE5EEC3EBE), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x044B2B6E105221DA, 0x3089BBC033F994AF), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x374A5A24AA8E6CC5, 0x29930FAA6215FA2B), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x30CD0F7AF0CF26F9, 0x06CCA6744DE7DCF5), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x1A6C9A1F6FE494A5, 0xA0CFAF77617E54DD), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x081AF6DAAB1C8717, 0xBFEDCE59AE3DC9AC), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x3518E44573AB68BA, 0xC96EE71AF9F8F546), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xF89E81FE8D73C96F, 0x4583A04577A0F21C), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xDF4026421CB61119, 0x14115A1F5139AFC7), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x91A20262C3E3A695, 0x0B3A102BFCDC6B1C), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x44F4C7CCFEB9EBFA, 0xF68394E6D56E5C2F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xB89F17C7021E9760, 0x430357EE0F7188EF), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xDA2D20EA4242B8A0, 0x0D1EC05B72E3838F), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x855DFEE1208D11B9, 0x77C6E3DDCFE30B85), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x9B3808439683FD58, 0x123DCBE4705AB25E), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xA42CF045C248A00A, 0x0C6C63C24EA0B0C1), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x320A83B6D00C8059, 0x796EDAB3EB7314BC), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x45253AC9ABFFC613, 0x8F92EA70195FB573), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x1A5D263B588274B6, 0x167D305F6C794179), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x709C1A837FE966AC, 0x75D8CE49E8A78EDB), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x8265C26F85E4145F, 0x932E6CCBF37CB600), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x3F252B3FEF983F27, 0x9370D7EEFEFA1A9E), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x66A334A4AEA41078, 0xCB52254E1E395231), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xFDD05C53B25F0035, 0xB7E3ECEE166C222F), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x25D932A77FFED81A, 0xA50D797B0FCA94E8), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x4A953B6F5F7D341C, 0xDC05CFB50DDB5DC1), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x838CB660C4F41F6D, 0x9E7D958697543495), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x4DF6EC1348A8F797, 0xA128E0CD69DB5A64), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x178CDFAB9A015295, 0x2BF40EA72E596D57), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x338FC99050E56AFD, 0x2AF41CF82BE602BF), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x62E02ED60D1E978E, 0xBF726B3E68C11E4D), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xFBAF92DD4C101502, 0x7AF2EDA6596B819D), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x0EF1241F65D4B50A, 0xE8D85DFA6AEDDB84), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x77FE024B5C9D4A18, 0xF19D48A932F6860F), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x9C88CBFA2E09D857, 0x0A0361704CBEEE1D), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x5B94127FA190E640, 0x8D1FEFF837A91268), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xB9C9105B7E063DDB, 0xF6A70E1D511B96FD), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xF0751AAE332B3ED1, 0xC40146F5C83C2533), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x579EB12F595F75AD, 0x151BF0504703B81B), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xF9CA152C03AC8C62, 0x1581336205E5CF47), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.DstAlphaGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x98ACD8BB5E195D0F, 0x91F937672BE899F0), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0xBF97F10FC301F44C, 0x75721789F0D48548), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x1B982263B8B08A10, 0x3350C76E2E1B27DF), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0xFF20AC79F64EDED8, 0xAF9025B2D97B9273), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x9FFD986600FB112F, 0x384FDDF4E060139A), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x0425E40B5B8B3B52, 0x5880CBED7CAB631C), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x16DAC8593F28623A, 0x233DBC82325B8AED), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xB37E5F234B9F0948, 0xD5F957A2ECD98FD6), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xCA0FDADD1D20DBE3, 0x1A5C15CCBF1AC538), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x1C48304D73A9DF3A, 0x891DB93FA36E3450), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x53200F2279B7FA39, 0x051C2462EBF6789C), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xB88BFB80714DCD5C, 0xEBD6938D744E6A41), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xE33DC2A25FC1A976, 0x08B3DBB1F3027D45), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xCE97E71615370316, 0xE131AE49D3A4D62B), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xE059FD265149B256, 0x94AF817AC348F61F), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x16D31333D477E231, 0x9A98AAC84F72CC62), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x47FC3B0776366D3C, 0xE96D9BD83B277874), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x7230401E3FEA1F3B, 0xF0D15F05D3D1E309), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x188212F9303742F5, 0x100C51CB96E03591), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x52B755D296B44DC5, 0x4003B87275625973), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xD873ED973ADF7EAD, 0x73E68B57D92034E7), new AdvancedBlendEntry(AdvancedBlendOp.Contrast, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(2f, 2f, 2f), new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x471F9FA34B945ACB, 0x10524D1410B3C402), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x99F569454EA0EF32, 0x6FC70A8B3A07DC8B), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x5AD55F950067AC7E, 0x4BA60A4FBABDD0AC), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x03FF2C858C9C4C5B, 0xE95AE7F561FB60E9), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x6DC0E510C7BCF9D2, 0xAE805D7CECDCB5C1), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x44832332CED5C054, 0x2F8D5536C085B30A), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x4AB4D387618AC51F, 0x495B46E0555F4B32), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x99282B49405A01A8, 0xD6FA93F864F24A8E), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x37B30C1064FBD23E, 0x5D068366F42317C2), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x760FAE9D59E04BC2, 0xA40AD483EA01435E), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0xE786950FD9D1C6EF, 0xF9FDD5AF6451D239), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x052458BB4788B0CA, 0x8AC58FDCA1F45EF5), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x6AFC3837D1D31920, 0xB9D49C2FE49642C6), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0xAFC2911949317E01, 0xD5B63636F5CB3422), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+            { new Hash128(0x13B46DF507CC2C53, 0x86DE26517E6BF0A7), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x5C372442474BE410, 0x79ECD3C0C496EF2E), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x74AAB45DBF5336E9, 0x01BFC4E181DAD442), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x43239E282A36C85C, 0x36FB65560E46AD0F), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x1A3BA8A7583B8F7A, 0xE64E41D548033180), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x32BBB9859E9B565D, 0x3D5CE94FE55F18B5), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0xD947A0766AE3C0FC, 0x391E5D53E86F4ED6), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0xBD9A7C08BDFD8CE6, 0x905407634901355E), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x8395475BCB0D7A8C, 0x48AF5DD501D44A70), new AdvancedBlendEntry(AdvancedBlendOp.Plus, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x80AAC23FEBD4A3E5, 0xEA8C70F0B4DE52DE), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x2F3AD1B0F1B3FD09, 0xC0EBC784BFAB8EA3), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x52B54032F2F70BFF, 0xC941D6FDED674765), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xCA7B86F72EC6A99B, 0x55868A131AFE359E), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x377919B60BD133CA, 0x0FD611627664EF40), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x9D4A0C5EE1153887, 0x7B869EBA218C589B), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x311F2A858545D123, 0xB4D09C802480AD62), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xCF78AA6A83AFA689, 0x9DC48B0C2182A3E1), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xC3018CD6F1CF62D1, 0x016E32DD9087B1BB), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x9CB62CE0E956EE29, 0x0FB67F503E60B3AD), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x3589A13C16EF3BFA, 0x15B29BFC91F3BDFB), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x3502CA5FB7529917, 0xFA51BFD0D1688071), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x62ADC25AD6D0A923, 0x76CB6D238276D3A3), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x09FDEB1116A9D52C, 0x85BB8627CD5C2733), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x0709FED1B65E18EB, 0x5BC3AA4D99EC19CF), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xB18D28AE5DE4C723, 0xE820AA2B75C9C02E), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x6743C51621497480, 0x4B164E40858834AE), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x63D1E181E34A2944, 0x1AE292C9D9F12819), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x079523298250BFF6, 0xC0C793510603CDB5), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x4C9D0A973C805EA6, 0xD1FF59AD5156B93C), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x1E914678F3057BCD, 0xD503AE389C12D229), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0x9FDBADE5556C5311, 0x03F0CBC798FC5C94), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xE39451534635403C, 0x606CC1CA1F452388), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x1D39F0F0A1008AA6, 0xBFDF2B97E6C3F125), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xDB81BED30D5BDBEA, 0xAF0B2856EB93AD2C), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x83F69CCF1D0A79B6, 0x70D31332797430AC), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x7B87F807AB7A8F5C, 0x1241A2A01FB31771), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xF557172E20D5272D, 0xC1961F8C7A5D2820), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0xA8476B3944DBBC9B, 0x84A2F6AF97B15FDF), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+            { new Hash128(0x3259602B55414DA3, 0x72AACCC00B5A9D10), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+            { new Hash128(0xC0CB8C10F36EDCD6, 0x8C2D088AD8191E1C), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x81806C451C6255EF, 0x5AA8AC9A08941A15), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xE55A6537F4568198, 0xCA8735390B799B19), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x5C044BA14536DDA3, 0xBCE0123ED7D510EC), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x6788346C405BE130, 0x372A4BB199C01F9F), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x510EDC2A34E2856B, 0xE1727A407E294254), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x4B7BE01BD398C7A8, 0x5BFF79BC00672C18), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x213B43845540CFEC, 0xDA857411CF1CCFCE), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x765AFA6732E783F1, 0x8F1CABF1BC78A014), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xA4A5DE1CC06F6CB1, 0xA0634A0011001709), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x81F32BD8816EA796, 0x697EE86683165170), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xB870C209EAA5F092, 0xAF5FD923909CAA1F), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+            { new Hash128(0x3649A9F5C936FB83, 0xDD7C834897AA182A), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xD72A2B1097A5995C, 0x3D41B2763A913654), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x551E212B9F6C454A, 0xB0DFA05BEB3C37FA), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x681B5A313B7416BF, 0xCB1CBAEEB4D81500), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x9343A18BD4B16777, 0xEDB4AC1C8972C3A4), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xC960BF6D8519DE28, 0x78D8557FD405D119), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x65A7B01FDC73A46C, 0x297E096ED5CC4D8A), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0xD9C99BA4A6CDC13B, 0x3CFF0ACEDC2EE150), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x6BC00DA6EB922BD1, 0x5FD4C11F2A685234), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+            { new Hash128(0x8652300E32D93050, 0x9460E7B449132371), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+        };
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs
new file mode 100644
index 0000000000..f06b4bf742
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs
@@ -0,0 +1,126 @@
+using Ryujinx.Graphics.GAL;
+
+namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
+{
+    /// <summary>
+    /// Fixed function alpha state used for a advanced blend function.
+    /// </summary>
+    struct FixedFunctionAlpha
+    {
+        /// <summary>
+        /// Fixed function alpha state with alpha blending disabled.
+        /// </summary>
+        public static FixedFunctionAlpha Disabled => new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, default, default, default);
+
+        /// <summary>
+        /// Individual enable bits for the RGB and alpha components.
+        /// </summary>
+        public BlendUcodeEnable Enable { get; }
+
+        /// <summary>
+        /// Alpha blend operation.
+        /// </summary>
+        public BlendOp AlphaOp { get; }
+
+        /// <summary>
+        /// Value multiplied with the blend source operand.
+        /// </summary>
+        public BlendFactor AlphaSrcFactor { get; }
+
+        /// <summary>
+        /// Value multiplied with the blend destination operand.
+        /// </summary>
+        public BlendFactor AlphaDstFactor { get; }
+
+        /// <summary>
+        /// Creates a new blend fixed function alpha state.
+        /// </summary>
+        /// <param name="enable">Individual enable bits for the RGB and alpha components</param>
+        /// <param name="alphaOp">Alpha blend operation</param>
+        /// <param name="alphaSrc">Value multiplied with the blend source operand</param>
+        /// <param name="alphaDst">Value multiplied with the blend destination operand</param>
+        public FixedFunctionAlpha(BlendUcodeEnable enable, BlendOp alphaOp, BlendFactor alphaSrc, BlendFactor alphaDst)
+        {
+            Enable = enable;
+            AlphaOp = alphaOp;
+            AlphaSrcFactor = alphaSrc;
+            AlphaDstFactor = alphaDst;
+        }
+
+        /// <summary>
+        /// Creates a new blend fixed function alpha state.
+        /// </summary>
+        /// <param name="alphaOp">Alpha blend operation</param>
+        /// <param name="alphaSrc">Value multiplied with the blend source operand</param>
+        /// <param name="alphaDst">Value multiplied with the blend destination operand</param>
+        public FixedFunctionAlpha(BlendOp alphaOp, BlendFactor alphaSrc, BlendFactor alphaDst) : this(BlendUcodeEnable.EnableRGB, alphaOp, alphaSrc, alphaDst)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Blend microcode assembly function delegate.
+    /// </summary>
+    /// <param name="asm">Assembler</param>
+    /// <returns>Fixed function alpha state for the microcode</returns>
+    delegate FixedFunctionAlpha GenUcodeFunc(ref UcodeAssembler asm);
+
+    /// <summary>
+    /// Advanced blend microcode state.
+    /// </summary>
+    struct AdvancedBlendUcode
+    {
+        /// <summary>
+        /// Advanced blend operation.
+        /// </summary>
+        public AdvancedBlendOp Op { get; }
+
+        /// <summary>
+        /// Advanced blend overlap mode.
+        /// </summary>
+        public AdvancedBlendOverlap Overlap { get; }
+
+        /// <summary>
+        /// Whenever the source input is pre-multiplied.
+        /// </summary>
+        public bool SrcPreMultiplied { get; }
+
+        /// <summary>
+        /// Fixed function alpha state.
+        /// </summary>
+        public FixedFunctionAlpha Alpha { get; }
+
+        /// <summary>
+        /// Microcode.
+        /// </summary>
+        public uint[] Code { get; }
+
+        /// <summary>
+        /// Constants used by the microcode.
+        /// </summary>
+        public RgbFloat[] Constants { get; }
+
+        /// <summary>
+        /// Creates a new advanced blend state.
+        /// </summary>
+        /// <param name="op">Advanced blend operation</param>
+        /// <param name="overlap">Advanced blend overlap mode</param>
+        /// <param name="srcPreMultiplied">Whenever the source input is pre-multiplied</param>
+        /// <param name="genFunc">Function that will generate the advanced blend microcode</param>
+        public AdvancedBlendUcode(
+            AdvancedBlendOp op,
+            AdvancedBlendOverlap overlap,
+            bool srcPreMultiplied,
+            GenUcodeFunc genFunc)
+        {
+            Op = op;
+            Overlap = overlap;
+            SrcPreMultiplied = srcPreMultiplied;
+
+            UcodeAssembler asm = new UcodeAssembler();
+            Alpha = genFunc(ref asm);
+            Code = asm.GetCode();
+            Constants = asm.GetConstants();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs
new file mode 100644
index 0000000000..f854787e08
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Collections.Generic;
+
+namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
+{
+    /// <summary>
+    /// Blend microcode instruction.
+    /// </summary>
+    enum Instruction
+    {
+        Mmadd = 0,
+        Mmsub = 1,
+        Min = 2,
+        Max = 3,
+        Rcp = 4,
+        Add = 5,
+        Sub = 6
+    }
+
+    /// <summary>
+    /// Blend microcode condition code.
+    /// </summary>
+    enum CC
+    {
+        F = 0,
+        T = 1,
+        EQ = 2,
+        NE = 3,
+        LT = 4,
+        LE = 5,
+        GT = 6,
+        GE = 7
+    }
+
+    /// <summary>
+    /// Blend microcode opend B or D value.
+    /// </summary>
+    enum OpBD
+    {
+        ConstantZero = 0x0,
+        ConstantOne = 0x1,
+        SrcRGB = 0x2,
+        SrcAAA = 0x3,
+        OneMinusSrcAAA = 0x4,
+        DstRGB = 0x5,
+        DstAAA = 0x6,
+        OneMinusDstAAA = 0x7,
+        Temp0 = 0x9,
+        Temp1 = 0xa,
+        Temp2 = 0xb,
+        PBR = 0xc,
+        ConstantRGB = 0xd
+    }
+
+    /// <summary>
+    /// Blend microcode operand A or C value.
+    /// </summary>
+    enum OpAC
+    {
+        SrcRGB = 0,
+        DstRGB = 1,
+        SrcAAA = 2,
+        DstAAA = 3,
+        Temp0 = 4,
+        Temp1 = 5,
+        Temp2 = 6,
+        PBR = 7
+    }
+
+    /// <summary>
+    /// Blend microcode destination operand.
+    /// </summary>
+    enum OpDst
+    {
+        Temp0 = 0,
+        Temp1 = 1,
+        Temp2 = 2,
+        PBR = 3
+    }
+
+    /// <summary>
+    /// Blend microcode input swizzle.
+    /// </summary>
+    enum Swizzle
+    {
+        RGB = 0,
+        GBR = 1,
+        RRR = 2,
+        GGG = 3,
+        BBB = 4,
+        RToA = 5
+    }
+
+    /// <summary>
+    /// Blend microcode output components.
+    /// </summary>
+    enum WriteMask
+    {
+        RGB = 0,
+        R = 1,
+        G = 2,
+        B = 3
+    }
+
+    /// <summary>
+    /// Floating-point RGB color values.
+    /// </summary>
+    struct RgbFloat
+    {
+        /// <summary>
+        /// Red component value.
+        /// </summary>
+        public float R { get; }
+
+        /// <summary>
+        /// Green component value.
+        /// </summary>
+        public float G { get; }
+
+        /// <summary>
+        /// Blue component value.
+        /// </summary>
+        public float B { get; }
+
+        /// <summary>
+        /// Creates a new floating-point RGB value.
+        /// </summary>
+        /// <param name="r">Red component value</param>
+        /// <param name="g">Green component value</param>
+        /// <param name="b">Blue component value</param>
+        public RgbFloat(float r, float g, float b)
+        {
+            R = r;
+            G = g;
+            B = b;
+        }
+    }
+
+    /// <summary>
+    /// Blend microcode destination operand, including swizzle, write mask and condition code update flag.
+    /// </summary>
+    struct Dest
+    {
+        public static Dest Temp0 => new Dest(OpDst.Temp0, Swizzle.RGB, WriteMask.RGB, false);
+        public static Dest Temp1 => new Dest(OpDst.Temp1, Swizzle.RGB, WriteMask.RGB, false);
+        public static Dest Temp2 => new Dest(OpDst.Temp2, Swizzle.RGB, WriteMask.RGB, false);
+        public static Dest PBR => new Dest(OpDst.PBR, Swizzle.RGB, WriteMask.RGB, false);
+
+        public Dest GBR => new Dest(Dst, Swizzle.GBR, WriteMask, WriteCC);
+        public Dest RRR => new Dest(Dst, Swizzle.RRR, WriteMask, WriteCC);
+        public Dest GGG => new Dest(Dst, Swizzle.GGG, WriteMask, WriteCC);
+        public Dest BBB => new Dest(Dst, Swizzle.BBB, WriteMask, WriteCC);
+        public Dest RToA => new Dest(Dst, Swizzle.RToA, WriteMask, WriteCC);
+
+        public Dest R => new Dest(Dst, Swizzle, WriteMask.R, WriteCC);
+        public Dest G => new Dest(Dst, Swizzle, WriteMask.G, WriteCC);
+        public Dest B => new Dest(Dst, Swizzle, WriteMask.B, WriteCC);
+
+        public Dest CC => new Dest(Dst, Swizzle, WriteMask, true);
+
+        public OpDst Dst { get; }
+        public Swizzle Swizzle { get; }
+        public WriteMask WriteMask { get; }
+        public bool WriteCC { get; }
+
+        /// <summary>
+        /// Creates a new blend microcode destination operand.
+        /// </summary>
+        /// <param name="dst">Operand</param>
+        /// <param name="swizzle">Swizzle</param>
+        /// <param name="writeMask">Write maks</param>
+        /// <param name="writeCC">Indicates if condition codes should be updated</param>
+        public Dest(OpDst dst, Swizzle swizzle, WriteMask writeMask, bool writeCC)
+        {
+            Dst = dst;
+            Swizzle = swizzle;
+            WriteMask = writeMask;
+            WriteCC = writeCC;
+        }
+    }
+
+    /// <summary>
+    /// Blend microcode operaiton.
+    /// </summary>
+    struct UcodeOp
+    {
+        public readonly uint Word;
+
+        /// <summary>
+        /// Creates a new blend microcode operation.
+        /// </summary>
+        /// <param name="cc">Condition code that controls whenever the operation is executed or not</param>
+        /// <param name="inst">Instruction</param>
+        /// <param name="constIndex">Index on the constant table of the constant used by any constant operand</param>
+        /// <param name="dest">Destination operand</param>
+        /// <param name="srcA">First input operand</param>
+        /// <param name="srcB">Second input operand</param>
+        /// <param name="srcC">Third input operand</param>
+        /// <param name="srcD">Fourth input operand</param>
+        public UcodeOp(CC cc, Instruction inst, int constIndex, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
+        {
+            Word = (uint)cc |
+                ((uint)inst << 3) |
+                ((uint)constIndex << 6) |
+                ((uint)srcA << 9) |
+                ((uint)srcB << 12) |
+                ((uint)srcC << 16) |
+                ((uint)srcD << 19) |
+                ((uint)dest.Swizzle << 23) |
+                ((uint)dest.WriteMask << 26) |
+                ((uint)dest.Dst << 28) |
+                (dest.WriteCC ? (1u << 31) : 0);
+        }
+    }
+
+    /// <summary>
+    /// Blend microcode assembler.
+    /// </summary>
+    struct UcodeAssembler
+    {
+        private List<uint> _code;
+        private RgbFloat[] _constants;
+        private int _constantIndex;
+
+        public void Mul(CC cc, Dest dest, OpAC srcA, OpBD srcB)
+        {
+            Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
+        }
+
+        public void Madd(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC)
+        {
+            Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, srcC, OpBD.ConstantOne);
+        }
+
+        public void Mmadd(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
+        {
+            Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, srcC, srcD);
+        }
+
+        public void Mmsub(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
+        {
+            Assemble(cc, Instruction.Mmsub, dest, srcA, srcB, srcC, srcD);
+        }
+
+        public void Min(CC cc, Dest dest, OpAC srcA, OpBD srcB)
+        {
+            Assemble(cc, Instruction.Min, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
+        }
+
+        public void Max(CC cc, Dest dest, OpAC srcA, OpBD srcB)
+        {
+            Assemble(cc, Instruction.Max, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
+        }
+
+        public void Rcp(CC cc, Dest dest, OpAC srcA)
+        {
+            Assemble(cc, Instruction.Rcp, dest, srcA, OpBD.ConstantZero, OpAC.SrcRGB, OpBD.ConstantZero);
+        }
+
+        public void Mov(CC cc, Dest dest, OpBD srcB)
+        {
+            Assemble(cc, Instruction.Add, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
+        }
+
+        public void Add(CC cc, Dest dest, OpBD srcB, OpBD srcD)
+        {
+            Assemble(cc, Instruction.Add, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, srcD);
+        }
+
+        public void Sub(CC cc, Dest dest, OpBD srcB, OpBD srcD)
+        {
+            Assemble(cc, Instruction.Sub, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, srcD);
+        }
+
+        private void Assemble(CC cc, Instruction inst, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
+        {
+            (_code ??= new List<uint>()).Add(new UcodeOp(cc, inst, _constantIndex, dest, srcA, srcB, srcC, srcD).Word);
+        }
+
+        public void SetConstant(int index, float r, float g, float b)
+        {
+            if (_constants == null)
+            {
+                _constants = new RgbFloat[index + 1];
+            }
+            else if (_constants.Length <= index)
+            {
+                Array.Resize(ref _constants, index + 1);
+            }
+
+            _constants[index] = new RgbFloat(r, g, b);
+            _constantIndex = index;
+        }
+
+        public uint[] GetCode()
+        {
+            return _code?.ToArray();
+        }
+
+        public RgbFloat[] GetConstants()
+        {
+            return _constants;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index 9b58e0148a..ecfd763f6b 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -1,5 +1,6 @@
 using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.GAL;
+using Ryujinx.Graphics.Gpu.Engine.Threed.Blender;
 using Ryujinx.Graphics.Gpu.Engine.Types;
 using Ryujinx.Graphics.Gpu.Image;
 using Ryujinx.Graphics.Gpu.Shader;
@@ -26,6 +27,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         private readonly GpuChannel _channel;
         private readonly DeviceStateWithShadow<ThreedClassState> _state;
         private readonly DrawState _drawState;
+        private readonly AdvancedBlendManager _blendManager;
 
         private readonly StateUpdateTracker<ThreedClassState> _updateTracker;
 
@@ -55,13 +57,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         /// <param name="channel">GPU channel</param>
         /// <param name="state">3D engine state</param>
         /// <param name="drawState">Draw state</param>
+        /// <param name="blendManager">Advanced blend manager</param>
         /// <param name="spec">Specialization state updater</param>
-        public StateUpdater(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState, SpecializationStateUpdater spec)
+        public StateUpdater(
+            GpuContext context,
+            GpuChannel channel,
+            DeviceStateWithShadow<ThreedClassState> state,
+            DrawState drawState,
+            AdvancedBlendManager blendManager,
+            SpecializationStateUpdater spec)
         {
             _context = context;
             _channel = channel;
             _state = state;
             _drawState = drawState;
+            _blendManager = blendManager;
             _currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages];
             _currentSpecState = spec;
 
@@ -84,6 +94,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
                 new StateUpdateCallbackEntry(UpdateVertexAttribState, nameof(ThreedClassState.VertexAttribState)),
 
                 new StateUpdateCallbackEntry(UpdateBlendState,
+                    nameof(ThreedClassState.BlendUcodeEnable),
+                    nameof(ThreedClassState.BlendUcodeSize),
                     nameof(ThreedClassState.BlendIndependent),
                     nameof(ThreedClassState.BlendConstant),
                     nameof(ThreedClassState.BlendStateCommon),
@@ -1154,6 +1166,20 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         /// </summary>
         private void UpdateBlendState()
         {
+            if (_state.State.BlendUcodeEnable != BlendUcodeEnable.Disabled)
+            {
+                if (_context.Capabilities.SupportsBlendEquationAdvanced && _blendManager.TryGetAdvancedBlend(out var blendDescriptor))
+                {
+                    // Try to HLE it using advanced blend on the host if we can.
+                    _context.Renderer.Pipeline.SetBlendState(blendDescriptor);
+                    return;
+                }
+                else
+                {
+                    // TODO: Blend emulation fallback.
+                }
+            }
+
             bool blendIndependent = _state.State.BlendIndependent;
             ColorF blendConstant = _state.State.BlendConstant;
 
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs
index 9a447a0bd9..caeee18e54 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs
@@ -2,6 +2,7 @@
 using Ryujinx.Graphics.GAL;
 using Ryujinx.Graphics.Gpu.Engine.GPFifo;
 using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
+using Ryujinx.Graphics.Gpu.Engine.Threed.Blender;
 using System;
 using System.Collections.Generic;
 using System.Runtime.CompilerServices;
@@ -18,6 +19,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         private readonly DeviceStateWithShadow<ThreedClassState> _state;
 
         private readonly InlineToMemoryClass _i2mClass;
+        private readonly AdvancedBlendManager _blendManager;
         private readonly DrawManager _drawManager;
         private readonly SemaphoreUpdater _semaphoreUpdater;
         private readonly ConstantBufferUpdater _cbUpdater;
@@ -40,6 +42,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
                 { nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) },
                 { nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) },
                 { nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) },
+                { nameof(ThreedClassState.LoadBlendUcodeStart), new RwCallback(LoadBlendUcodeStart, null) },
+                { nameof(ThreedClassState.LoadBlendUcodeInstruction), new RwCallback(LoadBlendUcodeInstruction, null) },
                 { nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) },
                 { nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) },
                 { nameof(ThreedClassState.DrawVertexArrayBeginEndInstanceFirst), new RwCallback(DrawVertexArrayBeginEndInstanceFirst, null) },
@@ -75,9 +79,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
             var drawState = new DrawState();
 
             _drawManager = new DrawManager(context, channel, _state, drawState, spec);
+            _blendManager = new AdvancedBlendManager(_state);
             _semaphoreUpdater = new SemaphoreUpdater(context, channel, _state);
             _cbUpdater = new ConstantBufferUpdater(channel, _state);
-            _stateUpdater = new StateUpdater(context, channel, _state, drawState, spec);
+            _stateUpdater = new StateUpdater(context, channel, _state, drawState, _blendManager, spec);
 
             // This defaults to "always", even without any register write.
             // Reads just return 0, regardless of what was set there.
@@ -283,6 +288,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
             _context.Renderer.Pipeline.TextureBarrier();
         }
 
+        /// <summary>
+        /// Sets the start offset of the blend microcode in memory.
+        /// </summary>
+        /// <param name="argument">Method call argument</param>
+        private void LoadBlendUcodeStart(int argument)
+        {
+            _blendManager.LoadBlendUcodeStart(argument);
+        }
+
+        /// <summary>
+        /// Pushes one word of blend microcode.
+        /// </summary>
+        /// <param name="argument">Method call argument</param>
+        private void LoadBlendUcodeInstruction(int argument)
+        {
+            _blendManager.LoadBlendUcodeInstruction(argument);
+        }
+
         /// <summary>
         /// Issues a texture barrier.
         /// This waits until previous texture writes from the GPU to finish, before
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
index 1498e27ba1..8f26f38ffc 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
@@ -5,6 +5,7 @@ using Ryujinx.Graphics.Gpu.Engine.Types;
 using Ryujinx.Graphics.Gpu.Image;
 using Ryujinx.Graphics.Shader;
 using System;
+using System.Runtime.CompilerServices;
 
 namespace Ryujinx.Graphics.Gpu.Engine.Threed
 {
@@ -214,6 +215,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
 #pragma warning restore CS0649
     }
 
+    /// <summary>
+    /// Indicates whenever the blend microcode processes RGB and alpha components.
+    /// </summary>
+    enum BlendUcodeEnable
+    {
+        Disabled = 0,
+        EnableRGB = 1,
+        EnableAlpha = 2,
+        EnableRGBA = 3
+    }
+
     /// <summary>
     /// Scissor state.
     /// </summary>
@@ -434,6 +446,49 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         TriangleRastFlip = 1 << 4
     }
 
+    /// <summary>
+    /// RGB color components packed as 16-bit float values.
+    /// </summary>
+    struct RgbHalf
+    {
+#pragma warning disable CS0649
+        public uint R;
+        public uint G;
+        public uint B;
+        public uint Padding;
+#pragma warning restore CS0649
+
+        /// <summary>
+        /// Unpacks the red color component as a 16-bit float value.
+        /// </summary>
+        /// <returns>The component value</returns>
+        public Half UnpackR()
+        {
+            ushort value = (ushort)R;
+            return Unsafe.As<ushort, Half>(ref value);
+        }
+
+        /// <summary>
+        /// Unpacks the green color component as a 16-bit float value.
+        /// </summary>
+        /// <returns>The component value</returns>
+        public Half UnpackG()
+        {
+            ushort value = (ushort)G;
+            return Unsafe.As<ushort, Half>(ref value);
+        }
+
+        /// <summary>
+        /// Unpacks the blue color component as a 16-bit float value.
+        /// </summary>
+        /// <returns>The component value</returns>
+        public Half UnpackB()
+        {
+            ushort value = (ushort)B;
+            return Unsafe.As<ushort, Half>(ref value);
+        }
+    }
+
     /// <summary>
     /// Condition for conditional rendering.
     /// </summary>
@@ -752,7 +807,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         public Boolean32 EarlyZForce;
         public fixed uint Reserved214[45];
         public uint SyncpointAction;
-        public fixed uint Reserved2CC[21];
+        public fixed uint Reserved2CC[10];
+        public uint BlendUcodeNormalizedDst;
+        public fixed uint Reserved2F8[10];
         public TessMode TessMode;
         public Array4<float> TessOuterLevel;
         public Array2<float> TessInnerLevel;
@@ -781,11 +838,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         public fixed uint ReservedDB8[2];
         public DepthBiasState DepthBiasState;
         public int PatchVertices;
-        public fixed uint ReservedDD0[4];
+        public BlendUcodeEnable BlendUcodeEnable;
+        public uint BlendUcodeSize;
+        public fixed uint ReservedDD8[2];
         public uint TextureBarrier;
         public uint WatchdogTimer;
         public Boolean32 PrimitiveRestartDrawArrays;
-        public fixed uint ReservedDEC[5];
+        public uint ReservedDEC;
+        public uint LoadBlendUcodeStart;
+        public uint LoadBlendUcodeInstruction;
+        public fixed uint ReservedDF8[2];
         public Array16<ScissorState> ScissorState;
         public fixed uint ReservedF00[21];
         public StencilBackMasks StencilBackMasks;
@@ -850,7 +912,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
         public fixed uint Reserved142C[2];
         public uint FirstVertex;
         public uint FirstInstance;
-        public fixed uint Reserved143C[53];
+        public fixed uint Reserved143C[17];
+        public Array8<RgbHalf> BlendUcodeConstants;
+        public fixed uint Reserved1500[4];
         public uint ClipDistanceEnable;
         public uint Reserved1514;
         public float PointSize;
diff --git a/Ryujinx.Graphics.OpenGL/EnumConversion.cs b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
index f262c584cb..c9a1eaa93f 100644
--- a/Ryujinx.Graphics.OpenGL/EnumConversion.cs
+++ b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
@@ -34,6 +34,126 @@ namespace Ryujinx.Graphics.OpenGL
             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)
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 8caf11dd54..846465260c 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.OpenGL
     {
         private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
         private static readonly Lazy<bool> _supportsAstcCompression              = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
+        private static readonly Lazy<bool> _supportsBlendEquationAdvanced        = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced"));
         private static readonly Lazy<bool> _supportsDrawTexture                  = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
         private static readonly Lazy<bool> _supportsFragmentShaderInterlock      = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
         private static readonly Lazy<bool> _supportsFragmentShaderOrdering       = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
@@ -51,6 +52,7 @@ namespace Ryujinx.Graphics.OpenGL
 
         public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
         public static bool SupportsAstcCompression              => _supportsAstcCompression.Value;
+        public static bool SupportsBlendEquationAdvanced        => _supportsBlendEquationAdvanced.Value;
         public static bool SupportsDrawTexture                  => _supportsDrawTexture.Value;
         public static bool SupportsFragmentShaderInterlock      => _supportsFragmentShaderInterlock.Value;
         public static bool SupportsFragmentShaderOrdering       => _supportsFragmentShaderOrdering.Value;
diff --git a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index 30ed942d32..722c4b4da6 100644
--- a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -119,6 +119,7 @@ namespace Ryujinx.Graphics.OpenGL
                 supportsR4G4B4A4Format: true,
                 supportsSnormBufferTextureFormat: false,
                 supports5BitComponentFormat: true,
+                supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
                 supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
                 supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
                 supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 8bcaf4c770..970feea0cc 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -59,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
         private uint _fragmentOutputMap;
         private uint _componentMasks;
         private uint _currentComponentMasks;
+        private bool _advancedBlendEnable;
 
         private uint _scissorEnables;
 
@@ -784,8 +785,26 @@ namespace Ryujinx.Graphics.OpenGL
             GL.Enable(EnableCap.AlphaTest);
         }
 
+        public void SetBlendState(AdvancedBlendDescriptor blend)
+        {
+            if (HwCapabilities.SupportsBlendEquationAdvanced)
+            {
+                GL.BlendEquation((BlendEquationMode)blend.Op.Convert());
+                GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendOverlapNv, (int)blend.Overlap.Convert());
+                GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendPremultipliedSrcNv, blend.SrcPreMultiplied ? 1 : 0);
+                GL.Enable(EnableCap.Blend);
+                _advancedBlendEnable = true;
+            }
+        }
+
         public void SetBlendState(int index, BlendDescriptor blend)
         {
+            if (_advancedBlendEnable)
+            {
+                GL.Disable(EnableCap.Blend);
+                _advancedBlendEnable = false;
+            }
+
             if (!blend.Enable)
             {
                 GL.Disable(IndexedEnableCap.Blend, index);
diff --git a/Ryujinx.Graphics.Vulkan/EnumConversion.cs b/Ryujinx.Graphics.Vulkan/EnumConversion.cs
index 0164ef85c8..6c273b0500 100644
--- a/Ryujinx.Graphics.Vulkan/EnumConversion.cs
+++ b/Ryujinx.Graphics.Vulkan/EnumConversion.cs
@@ -79,6 +79,60 @@ namespace Ryujinx.Graphics.Vulkan
             };
         }
 
+        public static Silk.NET.Vulkan.BlendOp Convert(this GAL.AdvancedBlendOp op)
+        {
+            return op switch
+            {
+                GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
+                GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
+                GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
+                GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
+                GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
+                GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
+                GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
+                GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
+                GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
+                GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
+                GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
+                GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
+                GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
+                GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
+                GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
+                GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
+                GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
+                GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
+                GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
+                GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
+                GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
+                GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
+                GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
+                GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
+                GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
+                GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
+                GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
+                GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
+                GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
+                GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
+                GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
+                GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
+                GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
+                GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
+                GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
+                GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
+                GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
+                GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
+                GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
+                GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
+                GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
+                GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
+                GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
+                GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
+                GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
+                GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
+                _ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
+            };
+        }
+
         public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
         {
             return op switch
@@ -92,6 +146,17 @@ namespace Ryujinx.Graphics.Vulkan
             };
         }
 
+        public static Silk.NET.Vulkan.BlendOverlapEXT Convert(this GAL.AdvancedBlendOverlap overlap)
+        {
+            return overlap switch
+            {
+                GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
+                GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
+                GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
+                _ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
+            };
+        }
+
         public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
         {
             return op switch
diff --git a/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
index 1ed2b0ccc6..4512d375f7 100644
--- a/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
+++ b/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs
@@ -18,6 +18,10 @@ namespace Ryujinx.Graphics.Vulkan
     {
         public readonly bool SupportsIndexTypeUint8;
         public readonly bool SupportsCustomBorderColor;
+        public readonly bool SupportsBlendEquationAdvanced;
+        public readonly bool SupportsBlendEquationAdvancedCorrelatedOverlap;
+        public readonly bool SupportsBlendEquationAdvancedNonPreMultipliedSrcColor;
+        public readonly bool SupportsBlendEquationAdvancedNonPreMultipliedDstColor;
         public readonly bool SupportsIndirectParameters;
         public readonly bool SupportsFragmentShaderInterlock;
         public readonly bool SupportsGeometryShaderPassthrough;
@@ -44,6 +48,10 @@ namespace Ryujinx.Graphics.Vulkan
         public HardwareCapabilities(
             bool supportsIndexTypeUint8,
             bool supportsCustomBorderColor,
+            bool supportsBlendEquationAdvanced,
+            bool supportsBlendEquationAdvancedCorrelatedOverlap,
+            bool supportsBlendEquationAdvancedNonPreMultipliedSrcColor,
+            bool supportsBlendEquationAdvancedNonPreMultipliedDstColor,
             bool supportsIndirectParameters,
             bool supportsFragmentShaderInterlock,
             bool supportsGeometryShaderPassthrough,
@@ -69,6 +77,10 @@ namespace Ryujinx.Graphics.Vulkan
         {
             SupportsIndexTypeUint8 = supportsIndexTypeUint8;
             SupportsCustomBorderColor = supportsCustomBorderColor;
+            SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
+            SupportsBlendEquationAdvancedCorrelatedOverlap = supportsBlendEquationAdvancedCorrelatedOverlap;
+            SupportsBlendEquationAdvancedNonPreMultipliedSrcColor = supportsBlendEquationAdvancedNonPreMultipliedSrcColor;
+            SupportsBlendEquationAdvancedNonPreMultipliedDstColor = supportsBlendEquationAdvancedNonPreMultipliedDstColor;
             SupportsIndirectParameters = supportsIndirectParameters;
             SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
             SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 8ed39ee26e..f779305dbf 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -112,11 +112,9 @@ namespace Ryujinx.Graphics.Vulkan
             var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
             new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
 
-            _newState.Initialize();
-            _newState.LineWidth = 1f;
-            _newState.SamplesCount = 1;
+            _storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
 
-            _storedBlend = new PipelineColorBlendAttachmentState[8];
+            _newState.Initialize();
         }
 
         public void Initialize()
@@ -676,6 +674,49 @@ namespace Ryujinx.Graphics.Vulkan
             // to avoid creating one version of the shader per reference value used.
         }
 
+        public void SetBlendState(AdvancedBlendDescriptor blend)
+        {
+            for (int index = 0; index < Constants.MaxRenderTargets; index++)
+            {
+                ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
+
+                if (index == 0)
+                {
+                    var blendOp = blend.Op.Convert();
+
+                    vkBlend = new PipelineColorBlendAttachmentState(
+                        blendEnable: true,
+                        colorBlendOp: blendOp,
+                        alphaBlendOp: blendOp,
+                        colorWriteMask: vkBlend.ColorWriteMask);
+
+                    if (Gd.Capabilities.SupportsBlendEquationAdvancedNonPreMultipliedSrcColor)
+                    {
+                        _newState.AdvancedBlendSrcPreMultiplied = blend.SrcPreMultiplied;
+                    }
+
+                    if (Gd.Capabilities.SupportsBlendEquationAdvancedCorrelatedOverlap)
+                    {
+                        _newState.AdvancedBlendOverlap = blend.Overlap.Convert();
+                    }
+                }
+                else
+                {
+                    vkBlend = new PipelineColorBlendAttachmentState(
+                        colorWriteMask: vkBlend.ColorWriteMask);
+                }
+
+                if (vkBlend.ColorWriteMask == 0)
+                {
+                    _storedBlend[index] = vkBlend;
+
+                    vkBlend = new PipelineColorBlendAttachmentState();
+                }
+            }
+
+            SignalStateChange();
+        }
+
         public void SetBlendState(int index, BlendDescriptor blend)
         {
             ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
@@ -709,6 +750,11 @@ namespace Ryujinx.Graphics.Vulkan
                 blend.BlendConstant.Blue,
                 blend.BlendConstant.Alpha);
 
+            // Reset advanced blend state back defaults to the cache to help the pipeline cache.
+            _newState.AdvancedBlendSrcPreMultiplied = true;
+            _newState.AdvancedBlendDstPreMultiplied = true;
+            _newState.AdvancedBlendOverlap = BlendOverlapEXT.UncorrelatedExt;
+
             SignalStateChange();
         }
 
diff --git a/Ryujinx.Graphics.Vulkan/PipelineState.cs b/Ryujinx.Graphics.Vulkan/PipelineState.cs
index 00b154a066..0d5494766e 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineState.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineState.cs
@@ -285,6 +285,24 @@ namespace Ryujinx.Graphics.Vulkan
             set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
         }
 
+        public bool AdvancedBlendSrcPreMultiplied
+        {
+            get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
+            set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFB) | ((value ? 1UL : 0UL) << 2);
+        }
+
+        public bool AdvancedBlendDstPreMultiplied
+        {
+            get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
+            set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFF7) | ((value ? 1UL : 0UL) << 3);
+        }
+
+        public BlendOverlapEXT AdvancedBlendOverlap
+        {
+            get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
+            set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
+        }
+
         public NativeArray<PipelineShaderStageCreateInfo> Stages;
         public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
         public PipelineLayout PipelineLayout;
@@ -303,6 +321,13 @@ namespace Ryujinx.Graphics.Vulkan
                     RequiredSubgroupSize = RequiredSubgroupSize
                 };
             }
+
+            AdvancedBlendSrcPreMultiplied = true;
+            AdvancedBlendDstPreMultiplied = true;
+            AdvancedBlendOverlap = BlendOverlapEXT.UncorrelatedExt;
+
+            LineWidth = 1f;
+            SamplesCount = 1;
         }
 
         public unsafe Auto<DisposablePipeline> CreateComputePipeline(
@@ -486,6 +511,23 @@ namespace Ryujinx.Graphics.Vulkan
                     PAttachments = pColorBlendAttachmentState
                 };
 
+                PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
+
+                if (!AdvancedBlendSrcPreMultiplied ||
+                    !AdvancedBlendDstPreMultiplied ||
+                    AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
+                {
+                    colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT()
+                    {
+                        SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
+                        SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
+                        DstPremultiplied = AdvancedBlendDstPreMultiplied,
+                        BlendOverlap = AdvancedBlendOverlap
+                    };
+
+                    colorBlendState.PNext = &colorBlendAdvancedState;
+                }
+
                 bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
                 int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
 
diff --git a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs
index 4401f032db..353b219ac0 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs
@@ -27,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
             ExtTransformFeedback.ExtensionName,
             KhrDrawIndirectCount.ExtensionName,
             KhrPushDescriptor.ExtensionName,
+            "VK_EXT_blend_operation_advanced",
             "VK_EXT_custom_border_color",
             "VK_EXT_descriptor_indexing", // Enabling this works around an issue with disposed buffer bindings on RADV.
             "VK_EXT_fragment_shader_interlock",
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index a7b4b41a72..4c7c731be0 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -149,6 +149,19 @@ namespace Ryujinx.Graphics.Vulkan
                 SType = StructureType.PhysicalDeviceProperties2
             };
 
+            PhysicalDeviceBlendOperationAdvancedPropertiesEXT propertiesBlendOperationAdvanced = new PhysicalDeviceBlendOperationAdvancedPropertiesEXT()
+            {
+                SType = StructureType.PhysicalDeviceBlendOperationAdvancedPropertiesExt
+            };
+
+            bool supportsBlendOperationAdvanced = supportedExtensions.Contains("VK_EXT_blend_operation_advanced");
+
+            if (supportsBlendOperationAdvanced)
+            {
+                propertiesBlendOperationAdvanced.PNext = properties2.PNext;
+                properties2.PNext = &propertiesBlendOperationAdvanced;
+            }
+
             PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
             {
                 SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
@@ -246,9 +259,9 @@ namespace Ryujinx.Graphics.Vulkan
                 portabilityFlags |= featuresPortabilitySubset.SamplerMipLodBias ? 0 : PortabilitySubsetFlags.NoLodBias;
             }
 
-            bool customBorderColorSupported = supportedExtensions.Contains("VK_EXT_custom_border_color") &&
-                                              featuresCustomBorderColor.CustomBorderColors &&
-                                              featuresCustomBorderColor.CustomBorderColorWithoutFormat;
+            bool supportsCustomBorderColor = supportedExtensions.Contains("VK_EXT_custom_border_color") &&
+                                             featuresCustomBorderColor.CustomBorderColors &&
+                                             featuresCustomBorderColor.CustomBorderColorWithoutFormat;
 
             ref var properties = ref properties2.Properties;
 
@@ -259,7 +272,11 @@ namespace Ryujinx.Graphics.Vulkan
 
             Capabilities = new HardwareCapabilities(
                 supportedExtensions.Contains("VK_EXT_index_type_uint8"),
-                customBorderColorSupported,
+                supportsCustomBorderColor,
+                supportsBlendOperationAdvanced,
+                propertiesBlendOperationAdvanced.AdvancedBlendCorrelatedOverlap,
+                propertiesBlendOperationAdvanced.AdvancedBlendNonPremultipliedSrcColor,
+                propertiesBlendOperationAdvanced.AdvancedBlendNonPremultipliedDstColor,
                 supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName),
                 supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
                 supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
@@ -526,6 +543,7 @@ namespace Ryujinx.Graphics.Vulkan
                 supportsR4G4B4A4Format: supportsR4G4B4A4Format,
                 supportsSnormBufferTextureFormat: true,
                 supports5BitComponentFormat: supports5BitComponentFormat,
+                supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
                 supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
                 supportsFragmentShaderOrderingIntel: false,
                 supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,