diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index f65f32540..68be1f5e0 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,26 +1,27 @@
name: Bug Report
description: File a bug report
-title: "[Bug]
"
+title: "[Bug]"
labels: bug
body:
- type: textarea
id: issue
attributes:
- label: Description of Issue
+ label: Description of the issue
description: What's the issue you encountered?
validations:
required: true
- type: textarea
id: repro
attributes:
- label: Reproduction Steps
+ label: Reproduction steps
description: How can the issue be reproduced?
+ placeholder: Describe each step as precisely as possible
validations:
required: true
- type: textarea
id: log
attributes:
- label: Log File
+ label: Log file
description: A log file will help our developers to better diagnose and fix the issue.
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area
validations:
@@ -29,55 +30,44 @@ body:
id: os
attributes:
label: OS
- placeholder: "Example: Windows 10"
+ placeholder: "e.g. Windows 10"
validations:
required: true
- type: input
id: ryujinx-version
attributes:
label: Ryujinx version
- placeholder: |
- - *(e.g. 1.0.470)*
+ placeholder: "e.g. 1.0.470"
validations:
required: true
- type: input
id: game-version
attributes:
label: Game version
- placeholder: |
- - *(e.g. 1.1.1)*
+ placeholder: "e.g. 1.1.1"
validations:
required: false
- type: input
id: cpu
attributes:
label: CPU
- placeholder: |
- - *(e.g. i7-6700)*
+ placeholder: "e.g. i7-6700"
validations:
required: false
- type: input
id: gpu
attributes:
label: GPU
- placeholder: |
- - *(e.g. NVIDIA RTX 2070)*
+ placeholder: "e.g. NVIDIA RTX 2070"
validations:
required: false
- type: input
id: ram
attributes:
label: RAM
- placeholder: |
- - *(e.g. 16GB)*
+ placeholder: "e.g. 16GB"
validations:
required: false
- - type: checkboxes
- attributes:
- label: Applied Mods?
- options:
- - label: "Yes"
- required: false
- type: textarea
id: mods
attributes:
@@ -93,4 +83,4 @@ body:
- Additional info about your environment:
- Any other information relevant to your issue.
validations:
- required: false
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index a9a5b504a..383bbb151 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -1,6 +1,6 @@
name: Feature Request
description: Suggest a new feature for Ryujinx.
-title: "[Feature Request] "
+title: "[Feature Request]"
body:
- type: textarea
id: overview
@@ -12,14 +12,14 @@ body:
- type: textarea
id: details
attributes:
- label: Smaller Details
+ label: Smaller details
description: These may include specific methods of implementation etc.
validations:
required: true
- type: textarea
id: request
attributes:
- label: Nature of Request
+ label: Nature of request
validations:
required: true
- type: textarea
diff --git a/.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml b/.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml
index 10e3bad37..d815ddfd9 100644
--- a/.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml
+++ b/.github/ISSUE_TEMPLATE/missing_cpu_instruction.yml
@@ -1,6 +1,6 @@
name: Missing CPU Instruction
description: CPU Instruction is missing in Ryujinx.
-title: "[CPU] "
+title: "[CPU]"
labels: [cpu, not-implemented]
body:
- type: textarea
diff --git a/.github/ISSUE_TEMPLATE/missing_service_call.yml b/.github/ISSUE_TEMPLATE/missing_service_call.yml
index 48d46d57f..80aae533b 100644
--- a/.github/ISSUE_TEMPLATE/missing_service_call.yml
+++ b/.github/ISSUE_TEMPLATE/missing_service_call.yml
@@ -5,7 +5,7 @@ body:
- type: textarea
id: instruction
attributes:
- label: Service Call
+ label: Service call
description: What service call is missing?
validations:
required: true
diff --git a/ARMeilleure/Instructions/InstEmitHash32.cs b/ARMeilleure/Instructions/InstEmitHash32.cs
index fec782dd8..5d39f8afc 100644
--- a/ARMeilleure/Instructions/InstEmitHash32.cs
+++ b/ARMeilleure/Instructions/InstEmitHash32.cs
@@ -1,9 +1,8 @@
using ARMeilleure.Decoders;
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
-
-using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitHashHelper;
+using static ARMeilleure.Instructions.InstEmitHelper;
namespace ARMeilleure.Instructions
{
diff --git a/ARMeilleure/Instructions/InstEmitHashHelper.cs b/ARMeilleure/Instructions/InstEmitHashHelper.cs
index 1dfe771c4..55a03a4f6 100644
--- a/ARMeilleure/Instructions/InstEmitHashHelper.cs
+++ b/ARMeilleure/Instructions/InstEmitHashHelper.cs
@@ -4,9 +4,8 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using System;
using System.Diagnostics;
-
-using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
using static ARMeilleure.Instructions.InstEmitSimdHelper;
+using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
namespace ARMeilleure.Instructions
{
diff --git a/ARMeilleure/Memory/IMemoryManager.cs b/ARMeilleure/Memory/IMemoryManager.cs
index c4ea70d17..5eb1fadd6 100644
--- a/ARMeilleure/Memory/IMemoryManager.cs
+++ b/ARMeilleure/Memory/IMemoryManager.cs
@@ -71,6 +71,7 @@ namespace ARMeilleure.Memory
/// Size of the region
/// True if the region was written, false if read
/// True if the access is precise, false otherwise
- void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false);
+ /// Optional ID of the handles that should not be signalled
+ void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null);
}
}
\ No newline at end of file
diff --git a/ARMeilleure/Signal/NativeSignalHandler.cs b/ARMeilleure/Signal/NativeSignalHandler.cs
index 77eabe267..cddeb8174 100644
--- a/ARMeilleure/Signal/NativeSignalHandler.cs
+++ b/ARMeilleure/Signal/NativeSignalHandler.cs
@@ -222,7 +222,7 @@ namespace ARMeilleure.Signal
// Tracking action should be non-null to call it, otherwise assume false return.
context.BranchIfFalse(skipActionLabel, trackingActionPtr);
- Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(_pageSize), isWrite, Const(0));
+ Operand result = context.Call(trackingActionPtr, OperandType.I32, offset, Const(_pageSize), isWrite);
context.Copy(inRegionLocal, result);
context.MarkLabel(skipActionLabel);
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 1b0b906f8..5de9461a1 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -19,17 +19,17 @@
-
+
-
-
+
+
-
-
-
-
+
+
+
+
@@ -44,12 +44,12 @@
-
+
-
+
-
\ No newline at end of file
+
diff --git a/README.md b/README.md
index 0f11daf15..fdb29a481 100644
--- a/README.md
+++ b/README.md
@@ -96,7 +96,7 @@ Ryujinx system files are stored in the `Ryujinx` folder. This folder is located
- **GPU**
- The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. There are currently four graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Aspect Ratio Adjustment, and Anisotropic Filtering. These enhancements can be adjusted or toggled as desired in the GUI.
+ The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum), Vulkan, or Metal (via MoltenVK) APIs through a custom build of OpenTK or Silk.NET respectively. There are currently six graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Anti-Aliasing, Scaling Filters (including FSR), Anisotropic Filtering and Aspect Ratio Adjustment. These enhancements can be adjusted or toggled as desired in the GUI.
- **Input**
diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
index 2eab59086..02da27769 100644
--- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
+++ b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
@@ -5,9 +5,8 @@ using Ryujinx.Memory;
using System;
using System.Collections.Concurrent;
using System.Threading;
-
-using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
+using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
namespace Ryujinx.Audio.Backends.SoundIo
{
diff --git a/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs b/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs
index 8c3442935..34231e614 100644
--- a/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Diagnostics;
-using Ryujinx.Audio.Renderer.Dsp.Effect;
+using Ryujinx.Audio.Renderer.Dsp.Effect;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter.Effect;
+using System;
+using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Dsp.Command
{
diff --git a/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs b/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
index b46a33fe0..7873c4d27 100644
--- a/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -380,7 +381,6 @@ namespace Ryujinx.Audio.Renderer.Dsp
return _normalCurveLut2F;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static void ResampleDefaultQuality(Span outputBuffer, ReadOnlySpan inputBuffer, float ratio, ref float fraction, int sampleCount, bool needPitch)
{
ReadOnlySpan parameters = GetDefaultParameter(ratio);
@@ -394,35 +394,33 @@ namespace Ryujinx.Audio.Renderer.Dsp
if (ratio == 1f)
{
fixed (short* pInput = inputBuffer)
+ fixed (float* pOutput = outputBuffer, pParameters = parameters)
{
- fixed (float* pOutput = outputBuffer, pParameters = parameters)
+ Vector128 parameter = Sse.LoadVector128(pParameters);
+
+ for (; i < (sampleCount & ~3); i += 4)
{
- Vector128 parameter = Sse.LoadVector128(pParameters);
+ Vector128 intInput0 = Sse41.ConvertToVector128Int32(pInput + (uint)i);
+ Vector128 intInput1 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 1);
+ Vector128 intInput2 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 2);
+ Vector128 intInput3 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 3);
- for (; i < (sampleCount & ~3); i += 4)
- {
- Vector128 intInput0 = Sse41.ConvertToVector128Int32(pInput + (uint)i);
- Vector128 intInput1 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 1);
- Vector128 intInput2 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 2);
- Vector128 intInput3 = Sse41.ConvertToVector128Int32(pInput + (uint)i + 3);
+ Vector128 input0 = Sse2.ConvertToVector128Single(intInput0);
+ Vector128 input1 = Sse2.ConvertToVector128Single(intInput1);
+ Vector128 input2 = Sse2.ConvertToVector128Single(intInput2);
+ Vector128 input3 = Sse2.ConvertToVector128Single(intInput3);
- Vector128 input0 = Sse2.ConvertToVector128Single(intInput0);
- Vector128 input1 = Sse2.ConvertToVector128Single(intInput1);
- Vector128 input2 = Sse2.ConvertToVector128Single(intInput2);
- Vector128 input3 = Sse2.ConvertToVector128Single(intInput3);
+ Vector128 mix0 = Sse.Multiply(input0, parameter);
+ Vector128 mix1 = Sse.Multiply(input1, parameter);
+ Vector128 mix2 = Sse.Multiply(input2, parameter);
+ Vector128 mix3 = Sse.Multiply(input3, parameter);
- Vector128 mix0 = Sse.Multiply(input0, parameter);
- Vector128 mix1 = Sse.Multiply(input1, parameter);
- Vector128 mix2 = Sse.Multiply(input2, parameter);
- Vector128 mix3 = Sse.Multiply(input3, parameter);
+ Vector128 mix01 = Sse3.HorizontalAdd(mix0, mix1);
+ Vector128 mix23 = Sse3.HorizontalAdd(mix2, mix3);
- Vector128 mix01 = Sse3.HorizontalAdd(mix0, mix1);
- Vector128 mix23 = Sse3.HorizontalAdd(mix2, mix3);
+ Vector128 mix0123 = Sse3.HorizontalAdd(mix01, mix23);
- Vector128 mix0123 = Sse3.HorizontalAdd(mix01, mix23);
-
- Sse.Store(pOutput + (uint)i, Sse41.RoundToNearestInteger(mix0123));
- }
+ Sse.Store(pOutput + (uint)i, Sse41.RoundToNearestInteger(mix0123));
}
}
@@ -431,62 +429,60 @@ namespace Ryujinx.Audio.Renderer.Dsp
else
{
fixed (short* pInput = inputBuffer)
+ fixed (float* pOutput = outputBuffer, pParameters = parameters)
{
- fixed (float* pOutput = outputBuffer, pParameters = parameters)
+ for (; i < (sampleCount & ~3); i += 4)
{
- for (; i < (sampleCount & ~3); i += 4)
- {
- uint baseIndex0 = (uint)(fraction * 128) * 4;
- uint inputIndex0 = (uint)inputBufferIndex;
+ uint baseIndex0 = (uint)(fraction * 128) * 4;
+ uint inputIndex0 = (uint)inputBufferIndex;
- fraction += ratio;
+ fraction += ratio;
- uint baseIndex1 = ((uint)(fraction * 128) & 127) * 4;
- uint inputIndex1 = (uint)inputBufferIndex + (uint)fraction;
+ uint baseIndex1 = ((uint)(fraction * 128) & 127) * 4;
+ uint inputIndex1 = (uint)inputBufferIndex + (uint)fraction;
- fraction += ratio;
+ fraction += ratio;
- uint baseIndex2 = ((uint)(fraction * 128) & 127) * 4;
- uint inputIndex2 = (uint)inputBufferIndex + (uint)fraction;
+ uint baseIndex2 = ((uint)(fraction * 128) & 127) * 4;
+ uint inputIndex2 = (uint)inputBufferIndex + (uint)fraction;
- fraction += ratio;
+ fraction += ratio;
- uint baseIndex3 = ((uint)(fraction * 128) & 127) * 4;
- uint inputIndex3 = (uint)inputBufferIndex + (uint)fraction;
+ uint baseIndex3 = ((uint)(fraction * 128) & 127) * 4;
+ uint inputIndex3 = (uint)inputBufferIndex + (uint)fraction;
- fraction += ratio;
- inputBufferIndex += (int)fraction;
+ fraction += ratio;
+ inputBufferIndex += (int)fraction;
- // Only keep lower part (safe as fraction isn't supposed to be negative)
- fraction -= (int)fraction;
+ // Only keep lower part (safe as fraction isn't supposed to be negative)
+ fraction -= (int)fraction;
- Vector128 parameter0 = Sse.LoadVector128(pParameters + baseIndex0);
- Vector128 parameter1 = Sse.LoadVector128(pParameters + baseIndex1);
- Vector128 parameter2 = Sse.LoadVector128(pParameters + baseIndex2);
- Vector128 parameter3 = Sse.LoadVector128(pParameters + baseIndex3);
+ Vector128 parameter0 = Sse.LoadVector128(pParameters + baseIndex0);
+ Vector128 parameter1 = Sse.LoadVector128(pParameters + baseIndex1);
+ Vector128 parameter2 = Sse.LoadVector128(pParameters + baseIndex2);
+ Vector128 parameter3 = Sse.LoadVector128(pParameters + baseIndex3);
- Vector128 intInput0 = Sse41.ConvertToVector128Int32(pInput + inputIndex0);
- Vector128 intInput1 = Sse41.ConvertToVector128Int32(pInput + inputIndex1);
- Vector128 intInput2 = Sse41.ConvertToVector128Int32(pInput + inputIndex2);
- Vector128 intInput3 = Sse41.ConvertToVector128Int32(pInput + inputIndex3);
+ Vector128 intInput0 = Sse41.ConvertToVector128Int32(pInput + inputIndex0);
+ Vector128 intInput1 = Sse41.ConvertToVector128Int32(pInput + inputIndex1);
+ Vector128 intInput2 = Sse41.ConvertToVector128Int32(pInput + inputIndex2);
+ Vector128 intInput3 = Sse41.ConvertToVector128Int32(pInput + inputIndex3);
- Vector128 input0 = Sse2.ConvertToVector128Single(intInput0);
- Vector128 input1 = Sse2.ConvertToVector128Single(intInput1);
- Vector128 input2 = Sse2.ConvertToVector128Single(intInput2);
- Vector128 input3 = Sse2.ConvertToVector128Single(intInput3);
+ Vector128 input0 = Sse2.ConvertToVector128Single(intInput0);
+ Vector128 input1 = Sse2.ConvertToVector128Single(intInput1);
+ Vector128 input2 = Sse2.ConvertToVector128Single(intInput2);
+ Vector128 input3 = Sse2.ConvertToVector128Single(intInput3);
- Vector128 mix0 = Sse.Multiply(input0, parameter0);
- Vector128 mix1 = Sse.Multiply(input1, parameter1);
- Vector128 mix2 = Sse.Multiply(input2, parameter2);
- Vector128 mix3 = Sse.Multiply(input3, parameter3);
+ Vector128 mix0 = Sse.Multiply(input0, parameter0);
+ Vector128 mix1 = Sse.Multiply(input1, parameter1);
+ Vector128 mix2 = Sse.Multiply(input2, parameter2);
+ Vector128 mix3 = Sse.Multiply(input3, parameter3);
- Vector128 mix01 = Sse3.HorizontalAdd(mix0, mix1);
- Vector128 mix23 = Sse3.HorizontalAdd(mix2, mix3);
+ Vector128 mix01 = Sse3.HorizontalAdd(mix0, mix1);
+ Vector128 mix23 = Sse3.HorizontalAdd(mix2, mix3);
- Vector128 mix0123 = Sse3.HorizontalAdd(mix01, mix23);
+ Vector128 mix0123 = Sse3.HorizontalAdd(mix01, mix23);
- Sse.Store(pOutput + (uint)i, Sse41.RoundToNearestInteger(mix0123));
- }
+ Sse.Store(pOutput + (uint)i, Sse41.RoundToNearestInteger(mix0123));
}
}
}
@@ -526,34 +522,59 @@ namespace Ryujinx.Audio.Renderer.Dsp
return _highCurveLut2F;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void ResampleHighQuality(Span outputBuffer, ReadOnlySpan inputBuffer, float ratio, ref float fraction, int sampleCount)
+ private static unsafe void ResampleHighQuality(Span outputBuffer, ReadOnlySpan inputBuffer, float ratio, ref float fraction, int sampleCount)
{
ReadOnlySpan parameters = GetHighParameter(ratio);
int inputBufferIndex = 0;
- // TODO: fast path
-
- for (int i = 0; i < sampleCount; i++)
+ if (Avx2.IsSupported)
{
- int baseIndex = (int)(fraction * 128) * 8;
- ReadOnlySpan parameter = parameters.Slice(baseIndex, 8);
- ReadOnlySpan currentInput = inputBuffer.Slice(inputBufferIndex, 8);
+ // Fast path; assumes 256-bit vectors for simplicity because the filter is 8 taps
+ fixed (short* pInput = inputBuffer)
+ fixed (float* pParameters = parameters)
+ {
+ for (int i = 0; i < sampleCount; i++)
+ {
+ int baseIndex = (int)(fraction * 128) * 8;
- outputBuffer[i] = (float)Math.Round(currentInput[0] * parameter[0] +
- currentInput[1] * parameter[1] +
- currentInput[2] * parameter[2] +
- currentInput[3] * parameter[3] +
- currentInput[4] * parameter[4] +
- currentInput[5] * parameter[5] +
- currentInput[6] * parameter[6] +
- currentInput[7] * parameter[7]);
+ Vector256 intInput = Avx2.ConvertToVector256Int32(pInput + inputBufferIndex);
+ Vector256 floatInput = Avx.ConvertToVector256Single(intInput);
+ Vector256 parameter = Avx.LoadVector256(pParameters + baseIndex);
+ Vector256 dp = Avx.DotProduct(floatInput, parameter, control: 0xFF);
- fraction += ratio;
- inputBufferIndex += (int)MathF.Truncate(fraction);
+ // avx2 does an 8-element dot product piecewise so we have to sum up 2 intermediate results
+ outputBuffer[i] = (float)Math.Round(dp[0] + dp[4]);
- fraction -= (int)fraction;
+ fraction += ratio;
+ inputBufferIndex += (int)MathF.Truncate(fraction);
+
+ fraction -= (int)fraction;
+ }
+ }
+ }
+ else
+ {
+ for (int i = 0; i < sampleCount; i++)
+ {
+ int baseIndex = (int)(fraction * 128) * 8;
+ ReadOnlySpan parameter = parameters.Slice(baseIndex, 8);
+ ReadOnlySpan currentInput = inputBuffer.Slice(inputBufferIndex, 8);
+
+ outputBuffer[i] = (float)Math.Round(currentInput[0] * parameter[0] +
+ currentInput[1] * parameter[1] +
+ currentInput[2] * parameter[2] +
+ currentInput[3] * parameter[3] +
+ currentInput[4] * parameter[4] +
+ currentInput[5] * parameter[5] +
+ currentInput[6] * parameter[6] +
+ currentInput[7] * parameter[7]);
+
+ fraction += ratio;
+ inputBufferIndex += (int)MathF.Truncate(fraction);
+
+ fraction -= (int)fraction;
+ }
}
}
diff --git a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
index 847acec2e..6cdab5a7b 100644
--- a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
@@ -2,6 +2,7 @@ using Ryujinx.Audio.Renderer.Server.Upsampler;
using Ryujinx.Common.Memory;
using System;
using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp
@@ -70,16 +71,32 @@ namespace Ryujinx.Audio.Renderer.Dsp
return;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
float DoFilterBank(ref UpsamplerBufferState state, in Array20 bank)
{
float result = 0.0f;
Debug.Assert(state.History.Length == HistoryLength);
Debug.Assert(bank.Length == FilterBankLength);
- for (int j = 0; j < FilterBankLength; j++)
+
+ int curIdx = 0;
+ if (Vector.IsHardwareAccelerated)
{
- result += bank[j] * state.History[j];
+ // Do SIMD-accelerated block operations where possible.
+ // Only about a 2x speedup since filter bank length is short
+ int stopIdx = FilterBankLength - (FilterBankLength % Vector.Count);
+ while (curIdx < stopIdx)
+ {
+ result += Vector.Dot(
+ new Vector(bank.AsSpan().Slice(curIdx, Vector.Count)),
+ new Vector(state.History.AsSpan().Slice(curIdx, Vector.Count)));
+ curIdx += Vector.Count;
+ }
+ }
+
+ while (curIdx < FilterBankLength)
+ {
+ result += bank[curIdx] * state.History[curIdx];
+ curIdx++;
}
return result;
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs
index f4e5ae829..32162abcd 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs
@@ -1,7 +1,7 @@
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Dsp.State;
-using Ryujinx.Audio.Renderer.Parameter.Effect;
using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Parameter.Effect;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System;
using System.Diagnostics;
diff --git a/Ryujinx.Ava/AppHost.cs b/Ryujinx.Ava/AppHost.cs
index 242c84e7f..eb22b39e9 100644
--- a/Ryujinx.Ava/AppHost.cs
+++ b/Ryujinx.Ava/AppHost.cs
@@ -171,6 +171,11 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState;
ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
+ ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
+ ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
+ ConfigurationState.Instance.Graphics.AntiAliasing.Event += UpdateAntiAliasing;
+ ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter;
+ ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel;
_gpuCancellationTokenSource = new CancellationTokenSource();
}
@@ -193,6 +198,17 @@ namespace Ryujinx.Ava
}
}
}
+ private void UpdateScalingFilterLevel(object sender, ReactiveEventArgs e)
+ {
+ _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
+ _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
+ }
+
+ private void UpdateScalingFilter(object sender, ReactiveEventArgs e)
+ {
+ _renderer.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
+ _renderer.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
+ }
private void ShowCursor()
{
@@ -345,6 +361,11 @@ namespace Ryujinx.Ava
}
}
+ private void UpdateAntiAliasing(object sender, ReactiveEventArgs e)
+ {
+ _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)e.NewValue);
+ }
+
private void UpdateDockedModeState(object sender, ReactiveEventArgs e)
{
Device?.System.ChangeDockedModeState(e.NewValue);
@@ -411,6 +432,9 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState;
ConfigurationState.Instance.System.EnableDockedMode.Event -= UpdateDockedModeState;
ConfigurationState.Instance.System.AudioVolume.Event -= UpdateAudioVolumeState;
+ ConfigurationState.Instance.Graphics.ScalingFilter.Event -= UpdateScalingFilter;
+ ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event -= UpdateScalingFilterLevel;
+ ConfigurationState.Instance.Graphics.AntiAliasing.Event -= UpdateAntiAliasing;
_topLevel.PointerMoved -= TopLevel_PointerMoved;
@@ -788,6 +812,10 @@ namespace Ryujinx.Ava
Device.Gpu.Renderer.Initialize(_glLogLevel);
+ _renderer?.Window?.SetAntiAliasing((Graphics.GAL.AntiAliasing)ConfigurationState.Instance.Graphics.AntiAliasing.Value);
+ _renderer?.Window?.SetScalingFilter((Graphics.GAL.ScalingFilter)ConfigurationState.Instance.Graphics.ScalingFilter.Value);
+ _renderer?.Window?.SetScalingFilterLevel(ConfigurationState.Instance.Graphics.ScalingFilterLevel.Value);
+
Width = (int)_rendererHost.Bounds.Width;
Height = (int)_rendererHost.Bounds.Height;
diff --git a/Ryujinx.Ava/Assets/Locales/en_US.json b/Ryujinx.Ava/Assets/Locales/en_US.json
index becbcbd8c..fb8f800c0 100644
--- a/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -626,6 +626,16 @@
"Recover": "Recover",
"UserProfilesRecoverHeading" : "Saves were found for the following accounts",
"UserProfilesRecoverEmptyList": "No profiles to recover",
+ "GraphicsAATooltip": "Applies anti-aliasing to the game render",
+ "GraphicsAALabel": "Anti-Aliasing:",
+ "GraphicsScalingFilterLabel": "Scaling Filter:",
+ "GraphicsScalingFilterTooltip": "Enables Framebuffer Scaling",
+ "GraphicsScalingFilterLevelLabel": "Level",
+ "GraphicsScalingFilterLevelTooltip": "Set Scaling Filter Level",
+ "SmaaLow": "SMAA Low",
+ "SmaaMedium": "SMAA Medium",
+ "SmaaHigh": "SMAA High",
+ "SmaaUltra": "SMAA Ultra",
"UserEditorTitle" : "Edit User",
"UserEditorTitleCreate" : "Create User"
}
diff --git a/Ryujinx.Ava/Common/ApplicationHelper.cs b/Ryujinx.Ava/Common/ApplicationHelper.cs
index 0b8bd8da1..276d18745 100644
--- a/Ryujinx.Ava/Common/ApplicationHelper.cs
+++ b/Ryujinx.Ava/Common/ApplicationHelper.cs
@@ -193,7 +193,7 @@ namespace Ryujinx.Ava.Common
{
using var ncaFile = new UniqueRef();
- pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
if (nca.Header.ContentType == NcaContentType.Program)
@@ -249,8 +249,8 @@ namespace Ryujinx.Ava.Common
using var uniqueSourceFs = new UniqueRef(ncaFileSystem);
using var uniqueOutputFs = new UniqueRef(new LocalFileSystem(destination));
- fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref());
- fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref());
+ fsClient.Register(source.ToU8Span(), ref uniqueSourceFs.Ref);
+ fsClient.Register(output.ToU8Span(), ref uniqueOutputFs.Ref);
(Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/", cancellationToken.Token);
diff --git a/Ryujinx.Ava/Modules/Updater/Updater.cs b/Ryujinx.Ava/Modules/Updater/Updater.cs
index 62dc17729..e89abd1da 100644
--- a/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -21,6 +21,7 @@ using System.Net.Http;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -57,7 +58,7 @@ namespace Ryujinx.Modules
// Detect current platform
if (OperatingSystem.IsMacOS())
{
- _platformExt = "osx_x64.zip";
+ _platformExt = "macos_universal.app.tar.gz";
}
else if (OperatingSystem.IsWindows())
{
@@ -132,8 +133,8 @@ namespace Ryujinx.Modules
}
}
- // If build not done, assume no new update are availaible.
- if (_buildUrl == null)
+ // If build not done, assume no new update are available.
+ if (_buildUrl is null)
{
if (showVersionUpToDate)
{
@@ -240,13 +241,13 @@ namespace Ryujinx.Modules
{
HttpClient result = new();
- // Required by GitHub to interract with APIs.
+ // Required by GitHub to interact with APIs.
result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
return result;
}
- public static async void UpdateRyujinx(Window parent, string downloadUrl)
+ private static async void UpdateRyujinx(Window parent, string downloadUrl)
{
_updateSuccessful = false;
@@ -286,24 +287,40 @@ namespace Ryujinx.Modules
if (_updateSuccessful)
{
- var shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
- LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
+ bool shouldRestart = true;
+
+ if (!OperatingSystem.IsMacOS())
+ {
+ shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
+ LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
+ }
if (shouldRestart)
{
+ List arguments = CommandLineState.Arguments.ToList();
string ryuName = Path.GetFileName(Environment.ProcessPath);
- string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
+ string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
+ string executablePath = Path.Combine(executableDirectory, ryuName);
- if (!Path.Exists(ryuExe))
+ if (!Path.Exists(executablePath))
{
- ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx");
+ executablePath = Path.Combine(executableDirectory, OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx");
}
- SetFileExecutable(ryuExe);
+ // On macOS we perform the update at relaunch.
+ if (OperatingSystem.IsMacOS())
+ {
+ string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
+ string newBundlePath = Path.Combine(UpdateDir, "Ryujinx.app");
+ string updaterScriptPath = Path.Combine(newBundlePath, "Contents", "Resources", "updater.sh");
+ string currentPid = Process.GetCurrentProcess().Id.ToString();
- Process.Start(ryuExe, CommandLineState.Arguments);
+ executablePath = "/bin/bash";
+ arguments.InsertRange(0, new List { updaterScriptPath, baseBundlePath, newBundlePath, currentPid });
+ }
+ Process.Start(executablePath, arguments);
Environment.Exit(0);
}
}
@@ -383,6 +400,15 @@ namespace Ryujinx.Modules
File.WriteAllBytes(updateFile, mergedFileBytes);
+ // On macOS, ensure that we remove the quarantine bit to prevent Gatekeeper from blocking execution.
+ if (OperatingSystem.IsMacOS())
+ {
+ using (Process xattrProcess = Process.Start("xattr", new List { "-d", "com.apple.quarantine", updateFile }))
+ {
+ xattrProcess.WaitForExit();
+ }
+ }
+
try
{
InstallUpdate(taskDialog, updateFile);
@@ -408,9 +434,9 @@ namespace Ryujinx.Modules
Logger.Warning?.Print(LogClass.Application, ex.Message);
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
- for (int j = 0; j < webClients.Count; j++)
+ foreach (WebClient webClient in webClients)
{
- webClients[j].CancelAsync();
+ webClient.CancelAsync();
}
DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
@@ -472,19 +498,74 @@ namespace Ryujinx.Modules
worker.Start();
}
- private static void SetFileExecutable(string path)
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
+ private static void ExtractTarGzipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
{
- const UnixFileMode ExecutableFileMode = UnixFileMode.UserExecute |
- UnixFileMode.UserWrite |
- UnixFileMode.UserRead |
- UnixFileMode.GroupRead |
- UnixFileMode.GroupWrite |
- UnixFileMode.OtherRead |
- UnixFileMode.OtherWrite;
+ using Stream inStream = File.OpenRead(archivePath);
+ using GZipInputStream gzipStream = new(inStream);
+ using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
- if (!OperatingSystem.IsWindows() && File.Exists(path))
+ TarEntry tarEntry;
+
+ while ((tarEntry = tarStream.GetNextEntry()) is not null)
{
- File.SetUnixFileMode(path, ExecutableFileMode);
+ if (tarEntry.IsDirectory)
+ {
+ continue;
+ }
+
+ string outPath = Path.Combine(outputDirectoryPath, tarEntry.Name);
+
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+
+ using (FileStream outStream = File.OpenWrite(outPath))
+ {
+ tarStream.CopyEntryContents(outStream);
+ }
+
+ File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
+
+ Dispatcher.UIThread.Post(() =>
+ {
+ if (tarEntry is null)
+ {
+ return;
+ }
+
+ taskDialog.SetProgressBarState(GetPercentage(tarEntry.Size, inStream.Length), TaskDialogProgressState.Normal);
+ });
+ }
+ }
+
+ private static void ExtractZipFile(TaskDialog taskDialog, string archivePath, string outputDirectoryPath)
+ {
+ using Stream inStream = File.OpenRead(archivePath);
+ using ZipFile zipFile = new(inStream);
+
+ double count = 0;
+ foreach (ZipEntry zipEntry in zipFile)
+ {
+ count++;
+ if (zipEntry.IsDirectory) continue;
+
+ string outPath = Path.Combine(outputDirectoryPath, zipEntry.Name);
+
+ Directory.CreateDirectory(Path.GetDirectoryName(outPath));
+
+ using (Stream zipStream = zipFile.GetInputStream(zipEntry))
+ using (FileStream outStream = File.OpenWrite(outPath))
+ {
+ zipStream.CopyTo(outStream);
+ }
+
+ File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
+
+ Dispatcher.UIThread.Post(() =>
+ {
+ taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
+ });
}
}
@@ -494,73 +575,21 @@ namespace Ryujinx.Modules
taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterExtracting];
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
- if (OperatingSystem.IsLinux())
+ await Task.Run(() =>
{
- using Stream inStream = File.OpenRead(updateFile);
- using GZipInputStream gzipStream = new(inStream);
- using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
-
- await Task.Run(() =>
+ if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
- TarEntry tarEntry;
- while ((tarEntry = tarStream.GetNextEntry()) != null)
- {
- if (tarEntry.IsDirectory) continue;
-
- string outPath = Path.Combine(UpdateDir, tarEntry.Name);
-
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
-
- using (FileStream outStream = File.OpenWrite(outPath))
- {
- tarStream.CopyEntryContents(outStream);
- }
-
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
-
- TarEntry entry = tarEntry;
-
- Dispatcher.UIThread.Post(() =>
- {
- taskDialog.SetProgressBarState(GetPercentage(entry.Size, inStream.Length), TaskDialogProgressState.Normal);
- });
- }
- });
-
- taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
- }
- else
- {
- using Stream inStream = File.OpenRead(updateFile);
- using ZipFile zipFile = new(inStream);
-
- await Task.Run(() =>
+ ExtractTarGzipFile(taskDialog, updateFile, UpdateDir);
+ }
+ else if (OperatingSystem.IsWindows())
{
- double count = 0;
- foreach (ZipEntry zipEntry in zipFile)
- {
- count++;
- if (zipEntry.IsDirectory) continue;
-
- string outPath = Path.Combine(UpdateDir, zipEntry.Name);
-
- Directory.CreateDirectory(Path.GetDirectoryName(outPath));
-
- using (Stream zipStream = zipFile.GetInputStream(zipEntry))
- using (FileStream outStream = File.OpenWrite(outPath))
- {
- zipStream.CopyTo(outStream);
- }
-
- File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
-
- Dispatcher.UIThread.Post(() =>
- {
- taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
- });
- }
- });
- }
+ ExtractZipFile(taskDialog, updateFile, UpdateDir);
+ }
+ else
+ {
+ throw new NotSupportedException();
+ }
+ });
// Delete downloaded zip
File.Delete(updateFile);
@@ -570,40 +599,42 @@ namespace Ryujinx.Modules
taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterRenaming];
taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
- // Replace old files
- await Task.Run(() =>
+ // NOTE: On macOS, replacement is delayed to the restart phase.
+ if (!OperatingSystem.IsMacOS())
{
- double count = 0;
- foreach (string file in allFiles)
+ // Replace old files
+ await Task.Run(() =>
{
- count++;
- try
+ double count = 0;
+ foreach (string file in allFiles)
{
- File.Move(file, file + ".ryuold");
-
- Dispatcher.UIThread.Post(() =>
+ count++;
+ try
{
- taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
- });
- }
- catch
- {
- Logger.Warning?.Print(LogClass.Application, LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.UpdaterRenameFailed, file));
- }
- }
+ File.Move(file, file + ".ryuold");
- Dispatcher.UIThread.Post(() =>
- {
- taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterAddingFiles];
- taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
+ Dispatcher.UIThread.Post(() =>
+ {
+ taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
+ });
+ }
+ catch
+ {
+ Logger.Warning?.Print(LogClass.Application, LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.UpdaterRenameFailed, file));
+ }
+ }
+
+ Dispatcher.UIThread.Post(() =>
+ {
+ taskDialog.SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterAddingFiles];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
+ });
+
+ MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
});
- MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
- });
-
- Directory.Delete(UpdateDir, true);
-
- SetFileExecutable(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"));
+ Directory.Delete(UpdateDir, true);
+ }
_updateSuccessful = true;
@@ -613,7 +644,7 @@ namespace Ryujinx.Modules
public static bool CanUpdate(bool showWarnings)
{
#if !DISABLE_UPDATER
- if (RuntimeInformation.OSArchitecture != Architecture.X64)
+ if (RuntimeInformation.OSArchitecture != Architecture.X64 && !OperatingSystem.IsMacOS())
{
if (showWarnings)
{
@@ -686,7 +717,7 @@ namespace Ryujinx.Modules
#endif
}
- // NOTE: This method should always reflect the latest build layout.s
+ // NOTE: This method should always reflect the latest build layout.
private static IEnumerable EnumerateFilesToDelete()
{
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir.
diff --git a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
index 6911a4d4c..1b857fae4 100644
--- a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
+++ b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
@@ -16,9 +16,9 @@ using Ryujinx.Ava.UI.Views.User;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using System;
-using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
namespace Ryujinx.Ava.UI.Controls
@@ -121,7 +121,7 @@ namespace Ryujinx.Ava.UI.Controls
using var saveDataIterator = new UniqueRef();
- HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref(), SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
+ HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
Span saveDataInfo = stackalloc SaveDataInfo[10];
diff --git a/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs b/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
index bb9681e22..7a29cc198 100644
--- a/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
+++ b/Ryujinx.Ava/UI/Helpers/LoggerAdapter.cs
@@ -6,8 +6,8 @@ namespace Ryujinx.Ava.UI.Helpers
{
using AvaLogger = Avalonia.Logging.Logger;
using AvaLogLevel = Avalonia.Logging.LogEventLevel;
- using RyuLogger = Ryujinx.Common.Logging.Logger;
using RyuLogClass = Ryujinx.Common.Logging.LogClass;
+ using RyuLogger = Ryujinx.Common.Logging.Logger;
internal class LoggerAdapter : Avalonia.Logging.ILogSink
{
diff --git a/Ryujinx.Ava/UI/Helpers/MetalHelper.cs b/Ryujinx.Ava/UI/Helpers/MetalHelper.cs
deleted file mode 100644
index 5eb8660a1..000000000
--- a/Ryujinx.Ava/UI/Helpers/MetalHelper.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-using System;
-using System.Runtime.Versioning;
-using System.Runtime.InteropServices;
-using Avalonia;
-
-namespace Ryujinx.Ava.UI.Helpers
-{
- public delegate void UpdateBoundsCallbackDelegate(Rect rect);
-
- [SupportedOSPlatform("macos")]
- static partial class MetalHelper
- {
- private const string LibObjCImport = "/usr/lib/libobjc.A.dylib";
-
- private struct Selector
- {
- public readonly IntPtr NativePtr;
-
- public unsafe Selector(string value)
- {
- int size = System.Text.Encoding.UTF8.GetMaxByteCount(value.Length);
- byte* data = stackalloc byte[size];
-
- fixed (char* pValue = value)
- {
- System.Text.Encoding.UTF8.GetBytes(pValue, value.Length, data, size);
- }
-
- NativePtr = sel_registerName(data);
- }
-
- public static implicit operator Selector(string value) => new Selector(value);
- }
-
- private static unsafe IntPtr GetClass(string value)
- {
- int size = System.Text.Encoding.UTF8.GetMaxByteCount(value.Length);
- byte* data = stackalloc byte[size];
-
- fixed (char* pValue = value)
- {
- System.Text.Encoding.UTF8.GetBytes(pValue, value.Length, data, size);
- }
-
- return objc_getClass(data);
- }
-
- private struct NSPoint
- {
- public double X;
- public double Y;
-
- public NSPoint(double x, double y)
- {
- X = x;
- Y = y;
- }
- }
-
- private struct NSRect
- {
- public NSPoint Pos;
- public NSPoint Size;
-
- public NSRect(double x, double y, double width, double height)
- {
- Pos = new NSPoint(x, y);
- Size = new NSPoint(width, height);
- }
- }
-
- public static IntPtr GetMetalLayer(out IntPtr nsView, out UpdateBoundsCallbackDelegate updateBounds)
- {
- // Create a new CAMetalLayer.
- IntPtr layerClass = GetClass("CAMetalLayer");
- IntPtr metalLayer = IntPtr_objc_msgSend(layerClass, "alloc");
- objc_msgSend(metalLayer, "init");
-
- // Create a child NSView to render into.
- IntPtr nsViewClass = GetClass("NSView");
- IntPtr child = IntPtr_objc_msgSend(nsViewClass, "alloc");
- objc_msgSend(child, "init", new NSRect(0, 0, 0, 0));
-
- // Make its renderer our metal layer.
- objc_msgSend(child, "setWantsLayer:", (byte)1);
- objc_msgSend(child, "setLayer:", metalLayer);
- objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
-
- // Ensure the scale factor is up to date.
- updateBounds = (Rect rect) => {
- objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
- };
-
- nsView = child;
- return metalLayer;
- }
-
- public static void DestroyMetalLayer(IntPtr nsView, IntPtr metalLayer)
- {
- // TODO
- }
-
- [LibraryImport(LibObjCImport)]
- private static unsafe partial IntPtr sel_registerName(byte* data);
-
- [LibraryImport(LibObjCImport)]
- private static unsafe partial IntPtr objc_getClass(byte* data);
-
- [LibraryImport(LibObjCImport)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector);
-
- [LibraryImport(LibObjCImport)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value);
-
- [LibraryImport(LibObjCImport)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value);
-
- [LibraryImport(LibObjCImport)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point);
-
- [LibraryImport(LibObjCImport)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value);
-
- [LibraryImport(LibObjCImport, EntryPoint = "objc_msgSend")]
- private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector);
- }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs b/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
index 532f4dc27..a5c8b0031 100644
--- a/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
+++ b/Ryujinx.Ava/UI/Renderer/EmbeddedWindow.cs
@@ -2,9 +2,9 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Platform;
-using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Common.Configuration;
using Ryujinx.Ui.Common.Configuration;
+using Ryujinx.Ui.Common.Helper;
using SPB.Graphics;
using SPB.Platform;
using SPB.Platform.GLX;
@@ -30,6 +30,7 @@ namespace Ryujinx.Ava.UI.Renderer
protected IntPtr NsView { get; set; }
protected IntPtr MetalLayer { get; set; }
+ public delegate void UpdateBoundsCallbackDelegate(Rect rect);
private UpdateBoundsCallbackDelegate _updateBoundsCallback;
public event EventHandler WindowCreated;
@@ -237,8 +238,29 @@ namespace Ryujinx.Ava.UI.Renderer
[SupportedOSPlatform("macos")]
IPlatformHandle CreateMacOS()
{
- MetalLayer = MetalHelper.GetMetalLayer(out IntPtr nsView, out _updateBoundsCallback);
+ // Create a new CAMetalLayer.
+ IntPtr layerClass = ObjectiveC.objc_getClass("CAMetalLayer");
+ IntPtr metalLayer = ObjectiveC.IntPtr_objc_msgSend(layerClass, "alloc");
+ ObjectiveC.objc_msgSend(metalLayer, "init");
+ // Create a child NSView to render into.
+ IntPtr nsViewClass = ObjectiveC.objc_getClass("NSView");
+ IntPtr child = ObjectiveC.IntPtr_objc_msgSend(nsViewClass, "alloc");
+ ObjectiveC.objc_msgSend(child, "init", new ObjectiveC.NSRect(0, 0, 0, 0));
+
+ // Make its renderer our metal layer.
+ ObjectiveC.objc_msgSend(child, "setWantsLayer:", 1);
+ ObjectiveC.objc_msgSend(child, "setLayer:", metalLayer);
+ ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
+
+ // Ensure the scale factor is up to date.
+ _updateBoundsCallback = rect =>
+ {
+ ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
+ };
+
+ IntPtr nsView = child;
+ MetalLayer = metalLayer;
NsView = nsView;
return new PlatformHandle(nsView, "NSView");
@@ -260,7 +282,7 @@ namespace Ryujinx.Ava.UI.Renderer
[SupportedOSPlatform("macos")]
void DestroyMacOS()
{
- MetalHelper.DestroyMetalLayer(NsView, MetalLayer);
+ // TODO
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
index 5561a20ca..5311318c5 100644
--- a/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
@@ -3,7 +3,6 @@ using Avalonia.Collections;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Windows;
@@ -17,7 +16,6 @@ using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
-using System.Text.Json;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.ViewModels
@@ -31,7 +29,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private readonly byte[] _amiiboLogoBytes;
private readonly HttpClient _httpClient;
private readonly StyleableWindow _owner;
-
+
private Bitmap _amiiboImage;
private List _amiiboList;
private AvaloniaList _amiibos;
diff --git a/Ryujinx.Ava/UI/ViewModels/AvatarProfileViewModel.cs b/Ryujinx.Ava/UI/ViewModels/AvatarProfileViewModel.cs
index 1d0906237..b2b310149 100644
--- a/Ryujinx.Ava/UI/ViewModels/AvatarProfileViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/AvatarProfileViewModel.cs
@@ -246,7 +246,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
using var file = new UniqueRef();
- romfs.OpenFile(ref file.Ref(), ("/" + item.FullPath).ToU8Span(), OpenMode.Read)
+ romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read)
.ThrowIfFailure();
using (MemoryStream stream = new())
diff --git a/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs b/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
index f63fc3491..35256b3b5 100644
--- a/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
@@ -3,11 +3,8 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Svg.Skia;
using Avalonia.Threading;
-using LibHac.Bcat;
-using LibHac.Tools.Fs;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
-using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Windows;
diff --git a/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs b/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
index 373839193..a3663af3e 100644
--- a/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
@@ -7,8 +7,7 @@ using DynamicData;
using DynamicData.Binding;
using LibHac.Common;
using LibHac.Fs;
-using LibHac.FsSystem;
-using LibHac.Tools.Fs;
+using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
diff --git a/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs b/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
index 36b37b0f5..7045c9ed3 100644
--- a/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/SettingsViewModel.cs
@@ -45,6 +45,8 @@ namespace Ryujinx.Ava.UI.ViewModels
private KeyboardHotkeys _keyboardHotkeys;
private int _graphicsBackendIndex;
private string _customThemePath;
+ private int _scalingFilter;
+ private int _scalingFilterLevel;
public event Action CloseWindow;
public event Action SaveSettingsEvent;
@@ -153,6 +155,8 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsSDL2Enabled { get; set; }
public bool EnableCustomTheme { get; set; }
public bool IsCustomResolutionScaleActive => _resolutionScale == 4;
+ public bool IsScalingFilterActive => _scalingFilter == (int)Ryujinx.Common.Configuration.ScalingFilter.Fsr;
+
public bool IsVulkanSelected => GraphicsBackendIndex == 0;
public bool UseHypervisor { get; set; }
@@ -179,6 +183,18 @@ namespace Ryujinx.Ava.UI.ViewModels
public int AudioBackend { get; set; }
public int MaxAnisotropy { get; set; }
public int AspectRatio { get; set; }
+ public int AntiAliasingEffect { get; set; }
+ public string ScalingFilterLevelText => ScalingFilterLevel.ToString("0");
+ public int ScalingFilterLevel
+ {
+ get => _scalingFilterLevel;
+ set
+ {
+ _scalingFilterLevel = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(ScalingFilterLevelText));
+ }
+ }
public int OpenglDebugLevel { get; set; }
public int MemoryMode { get; set; }
public int BaseStyleIndex { get; set; }
@@ -192,6 +208,16 @@ namespace Ryujinx.Ava.UI.ViewModels
OnPropertyChanged(nameof(IsVulkanSelected));
}
}
+ public int ScalingFilter
+ {
+ get => _scalingFilter;
+ set
+ {
+ _scalingFilter = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(IsScalingFilterActive));
+ }
+ }
public int PreferredGpuIndex { get; set; }
@@ -365,6 +391,9 @@ namespace Ryujinx.Ava.UI.ViewModels
AspectRatio = (int)config.Graphics.AspectRatio.Value;
GraphicsBackendMultithreadingIndex = (int)config.Graphics.BackendThreading.Value;
ShaderDumpPath = config.Graphics.ShadersDumpPath;
+ AntiAliasingEffect = (int)config.Graphics.AntiAliasing.Value;
+ ScalingFilter = (int)config.Graphics.ScalingFilter.Value;
+ ScalingFilterLevel = config.Graphics.ScalingFilterLevel.Value;
// Audio
AudioBackend = (int)config.System.AudioBackend.Value;
@@ -447,6 +476,9 @@ namespace Ryujinx.Ava.UI.ViewModels
config.Graphics.ResScaleCustom.Value = CustomResolutionScale;
config.Graphics.MaxAnisotropy.Value = MaxAnisotropy == 0 ? -1 : MathF.Pow(2, MaxAnisotropy);
config.Graphics.AspectRatio.Value = (AspectRatio)AspectRatio;
+ config.Graphics.AntiAliasing.Value = (AntiAliasing)AntiAliasingEffect;
+ config.Graphics.ScalingFilter.Value = (ScalingFilter)ScalingFilter;
+ config.Graphics.ScalingFilterLevel.Value = ScalingFilterLevel;
if (ConfigurationState.Instance.Graphics.BackendThreading != (BackendThreading)GraphicsBackendMultithreadingIndex)
{
diff --git a/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
index 3d0b20f7e..dd9e1b961 100644
--- a/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
@@ -105,13 +105,13 @@ public class TitleUpdateViewModel : BaseModel
AddUpdate(path);
}
- // NOTE: Save the list again to remove leftovers.
- Save();
-
TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected, null);
SelectedUpdate = selected;
+ // NOTE: Save the list again to remove leftovers.
+ Save();
+
SortUpdates();
}
@@ -170,7 +170,7 @@ public class TitleUpdateViewModel : BaseModel
using UniqueRef nacpFile = new();
- controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref(), "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
TitleUpdates.Add(new TitleUpdateModel(controlData, path));
diff --git a/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs b/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
index 9d981128c..558cad5a7 100644
--- a/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs
@@ -126,7 +126,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{
using var file = new UniqueRef();
- romfs.OpenFile(ref file.Ref(), ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
using (MemoryStream stream = new())
using (MemoryStream streamPng = new())
diff --git a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
index 11ecd0fc9..1c6f4265c 100644
--- a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -1,8 +1,8 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
-using LibHac.FsSystem;
using LibHac.Ncm;
+using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
diff --git a/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml b/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
index fb30fb7f4..8e4122f38 100644
--- a/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
+++ b/Ryujinx.Ava/UI/Views/Settings/SettingsGraphicsView.axaml
@@ -7,6 +7,7 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ Design.Width="1000"
mc:Ignorable="d"
x:CompileBindings="True"
x:DataType="viewModels:SettingsViewModel">
@@ -111,6 +112,83 @@
Minimum="0.1"
Value="{Binding CustomResolutionScale}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
();
- _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref(), SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
+ _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref, SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
Span saveDataInfo = stackalloc SaveDataInfo[10];
diff --git a/Ryujinx.Common/Configuration/AntiAliasing.cs b/Ryujinx.Common/Configuration/AntiAliasing.cs
new file mode 100644
index 000000000..6543598c7
--- /dev/null
+++ b/Ryujinx.Common/Configuration/AntiAliasing.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.Common.Configuration
+{
+ public enum AntiAliasing
+ {
+ None,
+ Fxaa,
+ SmaaLow,
+ SmaaMedium,
+ SmaaHigh,
+ SmaaUltra
+ }
+}
diff --git a/Ryujinx.Common/Configuration/AppDataManager.cs b/Ryujinx.Common/Configuration/AppDataManager.cs
index 42b76453b..d6e778430 100644
--- a/Ryujinx.Common/Configuration/AppDataManager.cs
+++ b/Ryujinx.Common/Configuration/AppDataManager.cs
@@ -45,7 +45,15 @@ namespace Ryujinx.Common.Configuration
public static void Initialize(string baseDirPath)
{
- string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ string appDataPath;
+ if (OperatingSystem.IsMacOS())
+ {
+ appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Application Support");
+ }
+ else
+ {
+ appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ }
if (appDataPath.Length == 0)
{
@@ -81,6 +89,21 @@ namespace Ryujinx.Common.Configuration
BaseDirPath = Path.GetFullPath(BaseDirPath); // convert relative paths
+ // NOTE: Moves the Ryujinx folder in `~/.config` to `~/Library/Application Support` if one is found
+ // and a Ryujinx folder does not already exist in Application Support.
+ // Also creates a symlink from `~/.config/Ryujinx` to `~/Library/Application Support/Ryujinx` to preserve backwards compatibility.
+ // This should be removed in the future.
+ if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
+ {
+ string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
+ if (Path.Exists(oldConfigPath) && !Path.Exists(BaseDirPath))
+ {
+ CopyDirectory(oldConfigPath, BaseDirPath);
+ Directory.Delete(oldConfigPath, true);
+ Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath);
+ }
+ }
+
SetupBasePaths();
}
@@ -92,6 +115,34 @@ namespace Ryujinx.Common.Configuration
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
}
+ private static void CopyDirectory(string sourceDir, string destinationDir)
+ {
+ var dir = new DirectoryInfo(sourceDir);
+
+ if (!dir.Exists)
+ {
+ throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
+ }
+
+ DirectoryInfo[] subDirs = dir.GetDirectories();
+ Directory.CreateDirectory(destinationDir);
+
+ foreach (FileInfo file in dir.GetFiles())
+ {
+ if (file.Name == ".DS_Store")
+ {
+ continue;
+ }
+
+ file.CopyTo(Path.Combine(destinationDir, file.Name));
+ }
+
+ foreach (DirectoryInfo subDir in subDirs)
+ {
+ CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name));
+ }
+ }
+
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;
public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName;
}
diff --git a/Ryujinx.Common/Configuration/ScalingFilter.cs b/Ryujinx.Common/Configuration/ScalingFilter.cs
new file mode 100644
index 000000000..2095b89b1
--- /dev/null
+++ b/Ryujinx.Common/Configuration/ScalingFilter.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Common.Configuration
+{
+ public enum ScalingFilter
+ {
+ Bilinear,
+ Nearest,
+ Fsr
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs
index c1abdba9b..4d48dd48d 100644
--- a/Ryujinx.Common/Logging/Logger.cs
+++ b/Ryujinx.Common/Logging/Logger.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.SystemInterop;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -14,6 +15,8 @@ namespace Ryujinx.Common.Logging
private static readonly List m_LogTargets;
+ private static readonly StdErrAdapter _stdErrAdapter;
+
public static event EventHandler Updated;
public readonly struct Log
@@ -77,7 +80,13 @@ namespace Ryujinx.Common.Logging
{
Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, FormatMessage(logClass, caller, "Stubbed. " + message), data));
}
- }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void PrintRawMsg(string message)
+ {
+ Updated?.Invoke(null, new LogEventArgs(Level, m_Time.Elapsed, Thread.CurrentThread.Name, message));
+ }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static string FormatMessage(LogClass Class, string Caller, string Message) => $"{Class} {Caller}: {Message}";
@@ -119,6 +128,8 @@ namespace Ryujinx.Common.Logging
Warning = new Log(LogLevel.Warning);
Info = new Log(LogLevel.Info);
Trace = new Log(LogLevel.Trace);
+
+ _stdErrAdapter = new StdErrAdapter();
}
public static void RestartTime()
@@ -164,6 +175,8 @@ namespace Ryujinx.Common.Logging
{
Updated = null;
+ _stdErrAdapter.Dispose();
+
foreach (var target in m_LogTargets)
{
target.Dispose();
diff --git a/Ryujinx.Common/ReleaseInformation.cs b/Ryujinx.Common/ReleaseInformation.cs
index d0e013282..601c05b17 100644
--- a/Ryujinx.Common/ReleaseInformation.cs
+++ b/Ryujinx.Common/ReleaseInformation.cs
@@ -40,14 +40,21 @@ namespace Ryujinx.Common
}
}
+#if FORCE_EXTERNAL_BASE_DIR
public static string GetBaseApplicationDirectory()
{
- if (IsFlatHubBuild())
+ return AppDataManager.BaseDirPath;
+ }
+#else
+ public static string GetBaseApplicationDirectory()
+ {
+ if (IsFlatHubBuild() || OperatingSystem.IsMacOS())
{
return AppDataManager.BaseDirPath;
}
return AppDomain.CurrentDomain.BaseDirectory;
}
+#endif
}
}
\ No newline at end of file
diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj
index ca5de76a6..c307f524e 100644
--- a/Ryujinx.Common/Ryujinx.Common.csproj
+++ b/Ryujinx.Common/Ryujinx.Common.csproj
@@ -3,6 +3,7 @@
net7.0
true
+ $(DefineConstants);$(ExtraDefineConstants)
diff --git a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs
index cd4a3d821..b0c15e491 100644
--- a/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs
+++ b/Ryujinx.Common/SystemInfo/LinuxSystemInfo.cs
@@ -1,9 +1,9 @@
+using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.Versioning;
-using Ryujinx.Common.Logging;
namespace Ryujinx.Common.SystemInfo
{
diff --git a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs b/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs
index ad022bdf0..06324a54c 100644
--- a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs
+++ b/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs
@@ -1,9 +1,9 @@
+using Ryujinx.Common.Logging;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
-using Ryujinx.Common.Logging;
namespace Ryujinx.Common.SystemInfo
{
diff --git a/Ryujinx.Common/SystemInfo/SystemInfo.cs b/Ryujinx.Common/SystemInfo/SystemInfo.cs
index 1db72d9b9..e9ce3c58a 100644
--- a/Ryujinx.Common/SystemInfo/SystemInfo.cs
+++ b/Ryujinx.Common/SystemInfo/SystemInfo.cs
@@ -1,8 +1,8 @@
-using System;
+using Ryujinx.Common.Logging;
+using System;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using System.Text;
-using Ryujinx.Common.Logging;
namespace Ryujinx.Common.SystemInfo
{
diff --git a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
index 11f0785e6..c3598a1eb 100644
--- a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
+++ b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
@@ -1,8 +1,8 @@
+using Ryujinx.Common.Logging;
using System;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
-using Ryujinx.Common.Logging;
namespace Ryujinx.Common.SystemInfo
{
diff --git a/Ryujinx.Common/SystemInterop/StdErrAdapter.cs b/Ryujinx.Common/SystemInterop/StdErrAdapter.cs
new file mode 100644
index 000000000..efb142184
--- /dev/null
+++ b/Ryujinx.Common/SystemInterop/StdErrAdapter.cs
@@ -0,0 +1,93 @@
+using Ryujinx.Common.Logging;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Threading;
+
+namespace Ryujinx.Common.SystemInterop
+{
+ public partial class StdErrAdapter : IDisposable
+ {
+ private bool _disposable = false;
+ private UnixStream _pipeReader;
+ private UnixStream _pipeWriter;
+ private Thread _worker;
+
+ public StdErrAdapter()
+ {
+ if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
+ {
+ RegisterPosix();
+ }
+ }
+
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
+ private void RegisterPosix()
+ {
+ const int stdErrFileno = 2;
+
+ (int readFd, int writeFd) = MakePipe();
+ dup2(writeFd, stdErrFileno);
+
+ _pipeReader = new UnixStream(readFd);
+ _pipeWriter = new UnixStream(writeFd);
+
+ _worker = new Thread(EventWorker);
+ _disposable = true;
+ _worker.Start();
+ }
+
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
+ private void EventWorker()
+ {
+ TextReader reader = new StreamReader(_pipeReader);
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ Logger.Error?.PrintRawMsg(line);
+ }
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposable)
+ {
+ if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
+ {
+ _pipeReader?.Close();
+ _pipeWriter?.Close();
+ }
+
+ _disposable = false;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static partial int dup2(int fd, int fd2);
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static unsafe partial int pipe(int* pipefd);
+
+ private static unsafe (int, int) MakePipe()
+ {
+ int *pipefd = stackalloc int[2];
+
+ if (pipe(pipefd) == 0)
+ {
+ return (pipefd[0], pipefd[1]);
+ }
+ else
+ {
+ throw new();
+ }
+ }
+ }
+}
diff --git a/Ryujinx.Common/SystemInterop/UnixStream.cs b/Ryujinx.Common/SystemInterop/UnixStream.cs
new file mode 100644
index 000000000..1d6449974
--- /dev/null
+++ b/Ryujinx.Common/SystemInterop/UnixStream.cs
@@ -0,0 +1,155 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace Ryujinx.Common.SystemInterop
+{
+ [SupportedOSPlatform("linux")]
+ [SupportedOSPlatform("macos")]
+ public partial class UnixStream : Stream, IDisposable
+ {
+ private const int InvalidFd = -1;
+
+ private int _fd;
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static partial long read(int fd, IntPtr buf, ulong count);
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static partial long write(int fd, IntPtr buf, ulong count);
+
+ [LibraryImport("libc", SetLastError = true)]
+ private static partial int close(int fd);
+
+ public UnixStream(int fd)
+ {
+ if (InvalidFd == fd)
+ {
+ throw new ArgumentException("Invalid file descriptor");
+ }
+
+ _fd = fd;
+
+ CanRead = read(fd, IntPtr.Zero, 0) != -1;
+ CanWrite = write(fd, IntPtr.Zero, 0) != -1;
+ }
+
+ ~UnixStream()
+ {
+ Close();
+ }
+
+ public override bool CanRead { get; }
+ public override bool CanWrite { get; }
+ public override bool CanSeek => false;
+
+ public override long Length => throw new NotSupportedException();
+
+ public override long Position
+ {
+ get => throw new NotSupportedException();
+ set => throw new NotSupportedException();
+ }
+
+ public override void Flush()
+ {
+ }
+
+ public override unsafe int Read([In, Out] byte[] buffer, int offset, int count)
+ {
+ if (offset < 0 || offset > (buffer.Length - count) || count < 0)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (buffer.Length == 0)
+ {
+ return 0;
+ }
+
+ long r = 0;
+ fixed (byte* buf = &buffer[offset])
+ {
+ do
+ {
+ r = read(_fd, (IntPtr)buf, (ulong)count);
+ } while (ShouldRetry(r));
+ }
+
+ return (int)r;
+ }
+
+ public override unsafe void Write(byte[] buffer, int offset, int count)
+ {
+ if (offset < 0 || offset > (buffer.Length - count) || count < 0)
+ {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (buffer.Length == 0)
+ {
+ return;
+ }
+
+ fixed (byte* buf = &buffer[offset])
+ {
+ long r = 0;
+ do {
+ r = write(_fd, (IntPtr)buf, (ulong)count);
+ } while (ShouldRetry(r));
+ }
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
+
+ public override void Close()
+ {
+ if (_fd == InvalidFd)
+ {
+ return;
+ }
+
+ Flush();
+
+ int r;
+ do {
+ r = close(_fd);
+ } while (ShouldRetry(r));
+
+ _fd = InvalidFd;
+ }
+
+ void IDisposable.Dispose()
+ {
+ Close();
+ }
+
+ private bool ShouldRetry(long r)
+ {
+ if (r == -1)
+ {
+ const int eintr = 4;
+
+ int errno = Marshal.GetLastPInvokeError();
+
+ if (errno == eintr)
+ {
+ return true;
+ }
+
+ throw new SystemException($"Operation failed with error 0x{errno:X}");
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs b/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs
index 222dcae1b..437e02aea 100644
--- a/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs
+++ b/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs
@@ -634,13 +634,13 @@ namespace Ryujinx.Cpu.AppleHv
///
/// This function also validates that the given range is both valid and mapped, and will throw if it is not.
///
- public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false)
+ public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null)
{
AssertValidAddressAndSize(va, size);
if (precise)
{
- Tracking.VirtualMemoryEvent(va, size, write, precise: true);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: true, exemptId);
return;
}
@@ -663,7 +663,7 @@ namespace Ryujinx.Cpu.AppleHv
if (state >= tag)
{
- Tracking.VirtualMemoryEvent(va, size, write);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: false, exemptId);
return;
}
else if (state == 0)
@@ -706,7 +706,7 @@ namespace Ryujinx.Cpu.AppleHv
// Only trigger tracking from reads if both bits are set on any page.
if (write || (pte & (pte >> 1) & BlockMappedMask) != 0)
{
- Tracking.VirtualMemoryEvent(va, size, write);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: false, exemptId);
break;
}
}
@@ -822,21 +822,21 @@ namespace Ryujinx.Cpu.AppleHv
}
///
- public CpuRegionHandle BeginTracking(ulong address, ulong size)
+ public CpuRegionHandle BeginTracking(ulong address, ulong size, int id)
{
- return new CpuRegionHandle(Tracking.BeginTracking(address, size));
+ return new CpuRegionHandle(Tracking.BeginTracking(address, size, id));
}
///
- public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity)
+ public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity, int id)
{
- return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity));
+ return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity, id));
}
///
- public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity)
+ public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity, int id)
{
- return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity));
+ return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity, id));
}
///
diff --git a/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs b/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs
index 8004d39bc..92d3c76ca 100644
--- a/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs
+++ b/Ryujinx.Cpu/IVirtualMemoryManagerTracked.cs
@@ -28,8 +28,9 @@ namespace Ryujinx.Cpu
///
/// CPU virtual address of the region
/// Size of the region
+ /// Handle ID
/// The memory tracking handle
- CpuRegionHandle BeginTracking(ulong address, ulong size);
+ CpuRegionHandle BeginTracking(ulong address, ulong size, int id);
///
/// Obtains a memory tracking handle for the given virtual region, with a specified granularity. This should be disposed when finished with.
@@ -38,8 +39,9 @@ namespace Ryujinx.Cpu
/// Size of the region
/// Handles to inherit state from or reuse. When none are present, provide null
/// Desired granularity of write tracking
+ /// Handle ID
/// The memory tracking handle
- CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity);
+ CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity, int id);
///
/// Obtains a smart memory tracking handle for the given virtual region, with a specified granularity. This should be disposed when finished with.
@@ -47,7 +49,8 @@ namespace Ryujinx.Cpu
/// CPU virtual address of the region
/// Size of the region
/// Desired granularity of write tracking
+ /// Handle ID
/// The memory tracking handle
- CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity);
+ CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity, int id);
}
}
diff --git a/Ryujinx.Cpu/Jit/MemoryManager.cs b/Ryujinx.Cpu/Jit/MemoryManager.cs
index 014d843b5..8542d53e2 100644
--- a/Ryujinx.Cpu/Jit/MemoryManager.cs
+++ b/Ryujinx.Cpu/Jit/MemoryManager.cs
@@ -629,31 +629,31 @@ namespace Ryujinx.Cpu.Jit
}
///
- public CpuRegionHandle BeginTracking(ulong address, ulong size)
+ public CpuRegionHandle BeginTracking(ulong address, ulong size, int id)
{
- return new CpuRegionHandle(Tracking.BeginTracking(address, size));
+ return new CpuRegionHandle(Tracking.BeginTracking(address, size, id));
}
///
- public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity)
+ public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity, int id)
{
- return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity));
+ return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity, id));
}
///
- public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity)
+ public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity, int id)
{
- return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity));
+ return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity, id));
}
///
- public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false)
+ public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null)
{
AssertValidAddressAndSize(va, size);
if (precise)
{
- Tracking.VirtualMemoryEvent(va, size, write, precise: true);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: true, exemptId);
return;
}
@@ -676,7 +676,7 @@ namespace Ryujinx.Cpu.Jit
if ((pte & tag) != 0)
{
- Tracking.VirtualMemoryEvent(va, size, write);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: false, exemptId);
break;
}
diff --git a/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs b/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs
index 856b6b9b0..090740abe 100644
--- a/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs
+++ b/Ryujinx.Cpu/Jit/MemoryManagerHostMapped.cs
@@ -518,13 +518,13 @@ namespace Ryujinx.Cpu.Jit
///
/// This function also validates that the given range is both valid and mapped, and will throw if it is not.
///
- public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false)
+ public void SignalMemoryTracking(ulong va, ulong size, bool write, bool precise = false, int? exemptId = null)
{
AssertValidAddressAndSize(va, size);
if (precise)
{
- Tracking.VirtualMemoryEvent(va, size, write, precise: true);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: true, exemptId);
return;
}
@@ -547,7 +547,7 @@ namespace Ryujinx.Cpu.Jit
if (state >= tag)
{
- Tracking.VirtualMemoryEvent(va, size, write);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: false, exemptId);
return;
}
else if (state == 0)
@@ -590,7 +590,7 @@ namespace Ryujinx.Cpu.Jit
// Only trigger tracking from reads if both bits are set on any page.
if (write || (pte & (pte >> 1) & BlockMappedMask) != 0)
{
- Tracking.VirtualMemoryEvent(va, size, write);
+ Tracking.VirtualMemoryEvent(va, size, write, precise: false, exemptId);
break;
}
}
@@ -706,21 +706,21 @@ namespace Ryujinx.Cpu.Jit
}
///
- public CpuRegionHandle BeginTracking(ulong address, ulong size)
+ public CpuRegionHandle BeginTracking(ulong address, ulong size, int id)
{
- return new CpuRegionHandle(Tracking.BeginTracking(address, size));
+ return new CpuRegionHandle(Tracking.BeginTracking(address, size, id));
}
///
- public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity)
+ public CpuMultiRegionHandle BeginGranularTracking(ulong address, ulong size, IEnumerable handles, ulong granularity, int id)
{
- return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity));
+ return new CpuMultiRegionHandle(Tracking.BeginGranularTracking(address, size, handles, granularity, id));
}
///
- public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity)
+ public CpuSmartMultiRegionHandle BeginSmartGranularTracking(ulong address, ulong size, ulong granularity, int id)
{
- return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity));
+ return new CpuSmartMultiRegionHandle(Tracking.BeginSmartGranularTracking(address, size, granularity, id));
}
///
diff --git a/Ryujinx.Cpu/MemoryEhMeilleure.cs b/Ryujinx.Cpu/MemoryEhMeilleure.cs
index 806ef8113..0b434ea74 100644
--- a/Ryujinx.Cpu/MemoryEhMeilleure.cs
+++ b/Ryujinx.Cpu/MemoryEhMeilleure.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.Cpu
{
public class MemoryEhMeilleure : IDisposable
{
- private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write, bool precise = false);
+ private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent;
diff --git a/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs b/Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
new file mode 100644
index 000000000..1f1f7c3f1
--- /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 000000000..4140bf497
--- /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 000000000..d4feb2b30
--- /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/AntiAliasing.cs b/Ryujinx.Graphics.GAL/AntiAliasing.cs
new file mode 100644
index 000000000..d4e5754d8
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/AntiAliasing.cs
@@ -0,0 +1,12 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public enum AntiAliasing
+ {
+ None,
+ Fxaa,
+ SmaaLow,
+ SmaaMedium,
+ SmaaHigh,
+ SmaaUltra
+ }
+}
diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index 7a1f44b6b..7822da211 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -23,8 +23,10 @@ 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 SupportsGeometryShader;
public readonly bool SupportsGeometryShaderPassthrough;
public readonly bool SupportsImageLoadFormatted;
public readonly bool SupportsLayerVertexTessellation;
@@ -64,8 +66,10 @@ namespace Ryujinx.Graphics.GAL
bool supportsR4G4B4A4Format,
bool supportsSnormBufferTextureFormat,
bool supports5BitComponentFormat,
+ bool supportsBlendEquationAdvanced,
bool supportsFragmentShaderInterlock,
bool supportsFragmentShaderOrderingIntel,
+ bool supportsGeometryShader,
bool supportsGeometryShaderPassthrough,
bool supportsImageLoadFormatted,
bool supportsLayerVertexTessellation,
@@ -102,8 +106,10 @@ namespace Ryujinx.Graphics.GAL
SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
Supports5BitComponentFormat = supports5BitComponentFormat;
+ SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
+ SupportsGeometryShader = supportsGeometryShader;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
SupportsImageLoadFormatted = supportsImageLoadFormatted;
SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 26d019eb4..0a362081c 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/IWindow.cs b/Ryujinx.Graphics.GAL/IWindow.cs
index a9bbbc5e0..1221d685a 100644
--- a/Ryujinx.Graphics.GAL/IWindow.cs
+++ b/Ryujinx.Graphics.GAL/IWindow.cs
@@ -9,5 +9,9 @@ namespace Ryujinx.Graphics.GAL
void SetSize(int width, int height);
void ChangeVSyncMode(bool vsyncEnabled);
+
+ void SetAntiAliasing(AntiAliasing antialiasing);
+ void SetScalingFilter(ScalingFilter type);
+ void SetScalingFilterLevel(float level);
}
}
diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
index 48873491f..063b7edf9 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(CommandType.EndHostConditionalRendering);
Register(CommandType.EndTransformFeedback);
Register(CommandType.SetAlphaTest);
+ Register(CommandType.SetBlendStateAdvanced);
Register(CommandType.SetBlendState);
Register(CommandType.SetDepthBias);
Register(CommandType.SetDepthClamp);
diff --git a/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
index c199ff34c..61e729b44 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 000000000..2ec10a503
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetBlendStateAdvancedCommand.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Graphics.GAL.Multithreading.Commands
+{
+ struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand
+ {
+ 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 ba120867c..1bdc9cf48 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().Set(blend);
+ _renderer.QueueCommand();
+ }
+
public void SetBlendState(int index, BlendDescriptor blend)
{
_renderer.New().Set(index, blend);
diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
index c4b62a25d..a647d37eb 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedWindow.cs
@@ -32,5 +32,11 @@ namespace Ryujinx.Graphics.GAL.Multithreading
}
public void ChangeVSyncMode(bool vsyncEnabled) { }
+
+ public void SetAntiAliasing(AntiAliasing effect) { }
+
+ public void SetScalingFilter(ScalingFilter type) { }
+
+ public void SetScalingFilterLevel(float level) { }
}
}
diff --git a/Ryujinx.Graphics.GAL/UpscaleType.cs b/Ryujinx.Graphics.GAL/UpscaleType.cs
new file mode 100644
index 000000000..442b65f24
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/UpscaleType.cs
@@ -0,0 +1,9 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public enum ScalingFilter
+ {
+ Bilinear,
+ Nearest,
+ Fsr
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
index f6effe2ed..e1d7e9407 100644
--- a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs
@@ -197,7 +197,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
if (target != null)
{
+ target.SynchronizeMemory();
target.SetData(data, 0, 0, new GAL.Rectangle(_dstX, _dstY, _lineLengthIn / target.Info.FormatInfo.BytesPerPixel, _lineCount));
+ target.SignalModified();
return;
}
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 000000000..a40b9cc47
--- /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 _entries = new()");
+ sb.AppendLine("{");
+
+ foreach (var entry in Table)
+ {
+ Hash128 hash = XXHash128.ComputeHash(MemoryMarshal.Cast(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 000000000..8072c6af2
--- /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
+{
+ ///
+ /// Advanced blend manager.
+ ///
+ class AdvancedBlendManager
+ {
+ private const int InstructionRamSize = 128;
+ private const int InstructionRamSizeMask = InstructionRamSize - 1;
+
+ private readonly DeviceStateWithShadow _state;
+
+ private readonly uint[] _code;
+ private int _ip;
+
+ ///
+ /// Creates a new instance of the advanced blend manager.
+ ///
+ /// GPU state of the channel owning this manager
+ public AdvancedBlendManager(DeviceStateWithShadow state)
+ {
+ _state = state;
+ _code = new uint[InstructionRamSize];
+ }
+
+ ///
+ /// Sets the start offset of the blend microcode in memory.
+ ///
+ /// Method call argument
+ public void LoadBlendUcodeStart(int argument)
+ {
+ _ip = argument;
+ }
+
+ ///
+ /// Pushes one word of blend microcode.
+ ///
+ /// Method call argument
+ public void LoadBlendUcodeInstruction(int argument)
+ {
+ _code[_ip++ & InstructionRamSizeMask] = (uint)argument;
+ }
+
+ ///
+ /// Tries to identify the current advanced blend function being used,
+ /// given the current state and microcode that was uploaded.
+ ///
+ /// Advanced blend descriptor
+ /// True if the function was found, false otherwise
+ public bool TryGetAdvancedBlend(out AdvancedBlendDescriptor descriptor)
+ {
+ Span currentCode = new Span(_code);
+ byte codeLength = (byte)_state.State.BlendUcodeSize;
+
+ if (currentCode.Length > codeLength)
+ {
+ currentCode = currentCode.Slice(0, codeLength);
+ }
+
+ Hash128 hash = XXHash128.ComputeHash(MemoryMarshal.Cast(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 000000000..d35d8abf4
--- /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
+{
+ ///
+ /// Advanced blend function entry.
+ ///
+ struct AdvancedBlendEntry
+ {
+ ///
+ /// Advanced blend operation.
+ ///
+ public AdvancedBlendOp Op { get; }
+
+ ///
+ /// Advanced blend overlap mode.
+ ///
+ public AdvancedBlendOverlap Overlap { get; }
+
+ ///
+ /// Whenever the source input is pre-multiplied.
+ ///
+ public bool SrcPreMultiplied { get; }
+
+ ///
+ /// Constants used by the microcode.
+ ///
+ public RgbFloat[] Constants { get; }
+
+ ///
+ /// Fixed function alpha state.
+ ///
+ public FixedFunctionAlpha Alpha { get; }
+
+ ///
+ /// Creates a new advanced blend function entry.
+ ///
+ /// Advanced blend operation
+ /// Advanced blend overlap mode
+ /// Whenever the source input is pre-multiplied
+ /// Constants used by the microcode
+ /// Fixed function alpha state
+ public AdvancedBlendEntry(
+ AdvancedBlendOp op,
+ AdvancedBlendOverlap overlap,
+ bool srcPreMultiplied,
+ RgbFloat[] constants,
+ FixedFunctionAlpha alpha)
+ {
+ Op = op;
+ Overlap = overlap;
+ SrcPreMultiplied = srcPreMultiplied;
+ Constants = constants;
+ Alpha = alpha;
+ }
+ }
+
+ ///
+ /// Pre-generated hash table with advanced blend functions used by the driver.
+ ///
+ static class AdvancedBlendPreGenTable
+ {
+ ///
+ /// Advanced blend functions dictionary.
+ ///
+ public static readonly IReadOnlyDictionary Entries = new Dictionary()
+ {
+ { new Hash128(0x19ECF57B83DE31F7, 0x5BAE759246F264C0), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xDE1B14A356A1A9ED, 0x59D803593C607C1D), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x1A3C3A6D32DEC368, 0xBCAE519EC6AAA045), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x6FD380261A63B240, 0x17C3B335DBB9E3DB), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x1D39164823D3A2D1, 0xC45350959CE1C8FB), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x4759E0E5DA54D5E8, 0x1FDD57C0C38AFA1F), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x337684D43CCE97FA, 0x0139E30CC529E1C9), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xDA59E85D8428992D, 0x1D3D7C64C9EF0132), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xA346A91311D72114, 0x151A27A3FB0A1904), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x8A307241061FACD6, 0xA39D1826440B8EE7), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xB3BE569485EFFFE0, 0x0BA4E269B3CFB165), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0xF364CAA94E160FEB, 0xBF364512C72A3797), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x6BF791AB4AC19C87, 0x6FA17A994EA0FCDE), new AdvancedBlendEntry(AdvancedBlendOp.InvertOvg, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x053C75A0AE0BB222, 0x03C791FEEB59754C), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x25762AB40B6CBDE9, 0x595E9A968AC4F01C), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x601C8CBEC07FF8FF, 0xB8E22882360E8695), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x3A55B7B78C76A7A8, 0x206F503B2D9FFEAA), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x80BC65C7831388E5, 0xC652457B2C766AEC), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x3D3A912E5833EE13, 0x307895951349EE33), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0x0A5194C5E6891106, 0xDD8EC6586106557C), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x8D77173D5E06E916, 0x06AB190E7D10F4D4), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x655B4EBC148981DA, 0x455999EF2B9BD28A), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x98F5437D5F518929, 0xBFF4A6E83183DB63), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x6ADDEFE3B9CEF2FD, 0xB6F6272AFECB1AAB), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x80953F0953BF05B1, 0xD59ABFAA34F8196F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xA401D9AA2A39C121, 0xFC0C8005C22AD7E3), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x06274FB7CA9CDD22, 0x6CE8188B1A9AB6EF), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x0B079BE7F7F70817, 0xB72E7736CA51E321), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0x66215C99403CEDDE, 0x900B733D62204C48), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x12DEF2AD900CAD6C, 0x58CF5CC3004910DF), new AdvancedBlendEntry(AdvancedBlendOp.Plus, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x272BA3A49F64DAE4, 0xAC70B96C00A99EAF), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x206C34AAA7D3F545, 0xDA4B30CACAA483A0), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xEC1B03E8C883F9C9, 0x2D3CA044C58C01B4), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x58A19A0135D68B31, 0x82F35B97AED068E5), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x20489F9AB36CC0E3, 0x20499874219E35EE), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x2EE2209021F6B977, 0xF3AFA1491B8B89FC), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xD8BA4DD2EDE4DC9E, 0x01006114977CF715), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0xD156B99835A2D8ED, 0x2D0BEE9E135EA7A7), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x20CE8C898ED4BE27, 0x1514900B6F5E8F66), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xCDE5F743820BA2D9, 0x917845FE2ECB083D), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x415A1A48E03AA6E7, 0x046D7EE33CA46B9A), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Disjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0x081AF6DAAB1C8717, 0xBFEDCE59AE3DC9AC), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x3518E44573AB68BA, 0xC96EE71AF9F8F546), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0xF89E81FE8D73C96F, 0x4583A04577A0F21C), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0xDF4026421CB61119, 0x14115A1F5139AFC7), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x91A20262C3E3A695, 0x0B3A102BFCDC6B1C), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x44F4C7CCFEB9EBFA, 0xF68394E6D56E5C2F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xB89F17C7021E9760, 0x430357EE0F7188EF), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xDA2D20EA4242B8A0, 0x0D1EC05B72E3838F), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x855DFEE1208D11B9, 0x77C6E3DDCFE30B85), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0x9B3808439683FD58, 0x123DCBE4705AB25E), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xA42CF045C248A00A, 0x0C6C63C24EA0B0C1), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x320A83B6D00C8059, 0x796EDAB3EB7314BC), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x709C1A837FE966AC, 0x75D8CE49E8A78EDB), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x8265C26F85E4145F, 0x932E6CCBF37CB600), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x3F252B3FEF983F27, 0x9370D7EEFEFA1A9E), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x4A953B6F5F7D341C, 0xDC05CFB50DDB5DC1), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x838CB660C4F41F6D, 0x9E7D958697543495), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x4DF6EC1348A8F797, 0xA128E0CD69DB5A64), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x178CDFAB9A015295, 0x2BF40EA72E596D57), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x338FC99050E56AFD, 0x2AF41CF82BE602BF), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x77FE024B5C9D4A18, 0xF19D48A932F6860F), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Conjoint, true, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xF9CA152C03AC8C62, 0x1581336205E5CF47), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.DstAlphaGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0x98ACD8BB5E195D0F, 0x91F937672BE899F0), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0xBF97F10FC301F44C, 0x75721789F0D48548), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x1B982263B8B08A10, 0x3350C76E2E1B27DF), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
+ { new Hash128(0xFF20AC79F64EDED8, 0xAF9025B2D97B9273), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x9FFD986600FB112F, 0x384FDDF4E060139A), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x0425E40B5B8B3B52, 0x5880CBED7CAB631C), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x16DAC8593F28623A, 0x233DBC82325B8AED), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0xB37E5F234B9F0948, 0xD5F957A2ECD98FD6), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xCA0FDADD1D20DBE3, 0x1A5C15CCBF1AC538), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xB88BFB80714DCD5C, 0xEBD6938D744E6A41), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xE33DC2A25FC1A976, 0x08B3DBB1F3027D45), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0xCE97E71615370316, 0xE131AE49D3A4D62B), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x7230401E3FEA1F3B, 0xF0D15F05D3D1E309), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
+ { new Hash128(0x188212F9303742F5, 0x100C51CB96E03591), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
+ { new Hash128(0x52B755D296B44DC5, 0x4003B87275625973), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x99F569454EA0EF32, 0x6FC70A8B3A07DC8B), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x5AD55F950067AC7E, 0x4BA60A4FBABDD0AC), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), 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(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x4AB4D387618AC51F, 0x495B46E0555F4B32), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
+ { new Hash128(0x99282B49405A01A8, 0xD6FA93F864F24A8E), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x37B30C1064FBD23E, 0x5D068366F42317C2), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
+ { new Hash128(0x760FAE9D59E04BC2, 0xA40AD483EA01435E), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty(), 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