aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs16
-rw-r--r--Ryujinx.Graphics.GAL/AdvancedBlendOp.cs52
-rw-r--r--Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs9
-rw-r--r--Ryujinx.Graphics.GAL/Capabilities.cs3
-rw-r--r--Ryujinx.Graphics.GAL/IPipeline.cs1
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs1
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/CommandType.cs1
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateAdvancedCommand.cs18
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs6
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs4226
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendManager.cs115
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs273
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs126
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs305
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs28
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs25
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs72
-rw-r--r--Ryujinx.Graphics.OpenGL/EnumConversion.cs120
-rw-r--r--Ryujinx.Graphics.OpenGL/HwCapabilities.cs2
-rw-r--r--Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs1
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs19
-rw-r--r--Ryujinx.Graphics.Vulkan/EnumConversion.cs65
-rw-r--r--Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs12
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineBase.cs54
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineState.cs42
-rw-r--r--Ryujinx.Graphics.Vulkan/VulkanInitialization.cs1
-rw-r--r--Ryujinx.Graphics.Vulkan/VulkanRenderer.cs26
27 files changed, 5605 insertions, 14 deletions
diff --git a/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs b/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
new file mode 100644
index 00000000..1f1f7c3f
--- /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 00000000..4140bf49
--- /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 00000000..d4feb2b3
--- /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 7a1f44b6..a24139eb 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 26d019eb..0a362081 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 48873491..063b7edf 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 c199ff34..61e729b4 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 00000000..2ec10a50
--- /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 ba120867..1bdc9cf4 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 00000000..a40b9cc4
--- /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 00000000..8072c6af
--- /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 00000000..d35d8abf
--- /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 00000000..f06b4bf7
--- /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 00000000..f854787e
--- /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 9b58e014..ecfd763f 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 9a447a0b..caeee18e 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.
@@ -284,6 +289,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <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
/// performing new operations with said textures.
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
index 1498e27b..8f26f38f 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
{
@@ -215,6 +216,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <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>
struct ScissorState
@@ -435,6 +447,49 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <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>
enum Condition
@@ -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 f262c584..c9a1eaa9 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 8caf11dd..84646526 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 30ed942d..722c4b4d 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 8bcaf4c7..970feea0 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 0164ef85..6c273b05 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 1ed2b0cc..4512d375 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 8ed39ee2..f779305d 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 00b154a0..0d549476 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 4401f032..353b219a 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 a7b4b41a..4c7c731b 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,