forked from Mirror/Ryujinx
Add support for advanced blend (part 1/2) (#2801)
* Add blend microcode registers * Add advanced blend support using host extension * Remove debug message * Use pre-generated table for blend functions * XML docs * Rename AdvancedBlendMode to AdvancedBlendOp for consistency * Remove redundant code * Fix some advanced blend related issues on Vulkan * Formatting
This commit is contained in:
parent
6bf460e104
commit
7aa430f1a5
27 changed files with 5605 additions and 14 deletions
16
Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
Normal file
16
Ryujinx.Graphics.GAL/AdvancedBlendDescriptor.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
Ryujinx.Graphics.GAL/AdvancedBlendOp.cs
Normal file
52
Ryujinx.Graphics.GAL/AdvancedBlendOp.cs
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
9
Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs
Normal file
9
Ryujinx.Graphics.GAL/AdvancedBlendOverlap.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public enum AdvancedBlendOverlap
|
||||||
|
{
|
||||||
|
Uncorrelated,
|
||||||
|
Disjoint,
|
||||||
|
Conjoint
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public readonly bool SupportsR4G4B4A4Format;
|
public readonly bool SupportsR4G4B4A4Format;
|
||||||
public readonly bool SupportsSnormBufferTextureFormat;
|
public readonly bool SupportsSnormBufferTextureFormat;
|
||||||
public readonly bool Supports5BitComponentFormat;
|
public readonly bool Supports5BitComponentFormat;
|
||||||
|
public readonly bool SupportsBlendEquationAdvanced;
|
||||||
public readonly bool SupportsFragmentShaderInterlock;
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
public readonly bool SupportsFragmentShaderOrderingIntel;
|
public readonly bool SupportsFragmentShaderOrderingIntel;
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
|
@ -64,6 +65,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
bool supportsR4G4B4A4Format,
|
bool supportsR4G4B4A4Format,
|
||||||
bool supportsSnormBufferTextureFormat,
|
bool supportsSnormBufferTextureFormat,
|
||||||
bool supports5BitComponentFormat,
|
bool supports5BitComponentFormat,
|
||||||
|
bool supportsBlendEquationAdvanced,
|
||||||
bool supportsFragmentShaderInterlock,
|
bool supportsFragmentShaderInterlock,
|
||||||
bool supportsFragmentShaderOrderingIntel,
|
bool supportsFragmentShaderOrderingIntel,
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
|
@ -102,6 +104,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
|
SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
|
||||||
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
|
||||||
Supports5BitComponentFormat = supports5BitComponentFormat;
|
Supports5BitComponentFormat = supports5BitComponentFormat;
|
||||||
|
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
||||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
|
|
@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void SetAlphaTest(bool enable, float reference, CompareOp op);
|
void SetAlphaTest(bool enable, float reference, CompareOp op);
|
||||||
|
|
||||||
|
void SetBlendState(AdvancedBlendDescriptor blend);
|
||||||
void SetBlendState(int index, BlendDescriptor blend);
|
void SetBlendState(int index, BlendDescriptor blend);
|
||||||
|
|
||||||
void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);
|
void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);
|
||||||
|
|
|
@ -98,6 +98,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
|
Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
|
||||||
Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
|
Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
|
||||||
Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
|
Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
|
||||||
|
Register<SetBlendStateAdvancedCommand>(CommandType.SetBlendStateAdvanced);
|
||||||
Register<SetBlendStateCommand>(CommandType.SetBlendState);
|
Register<SetBlendStateCommand>(CommandType.SetBlendState);
|
||||||
Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
|
Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
|
||||||
Register<SetDepthClampCommand>(CommandType.SetDepthClamp);
|
Register<SetDepthClampCommand>(CommandType.SetDepthClamp);
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
EndHostConditionalRendering,
|
EndHostConditionalRendering,
|
||||||
EndTransformFeedback,
|
EndTransformFeedback,
|
||||||
SetAlphaTest,
|
SetAlphaTest,
|
||||||
|
SetBlendStateAdvanced,
|
||||||
SetBlendState,
|
SetBlendState,
|
||||||
SetDepthBias,
|
SetDepthBias,
|
||||||
SetDepthClamp,
|
SetDepthClamp,
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||||
|
{
|
||||||
|
struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand<SetBlendStateAdvancedCommand>
|
||||||
|
{
|
||||||
|
public CommandType CommandType => CommandType.SetBlendStateAdvanced;
|
||||||
|
private AdvancedBlendDescriptor _blend;
|
||||||
|
|
||||||
|
public void Set(AdvancedBlendDescriptor blend)
|
||||||
|
{
|
||||||
|
_blend = blend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Run(ref SetBlendStateAdvancedCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
|
{
|
||||||
|
renderer.Pipeline.SetBlendState(command._blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,6 +131,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBlendState(AdvancedBlendDescriptor blend)
|
||||||
|
{
|
||||||
|
_renderer.New<SetBlendStateAdvancedCommand>().Set(blend);
|
||||||
|
_renderer.QueueCommand();
|
||||||
|
}
|
||||||
|
|
||||||
public void SetBlendState(int index, BlendDescriptor blend)
|
public void SetBlendState(int index, BlendDescriptor blend)
|
||||||
{
|
{
|
||||||
_renderer.New<SetBlendStateCommand>().Set(index, blend);
|
_renderer.New<SetBlendStateCommand>().Set(index, blend);
|
||||||
|
|
4226
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs
Normal file
4226
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendFunctions.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,115 @@
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend manager.
|
||||||
|
/// </summary>
|
||||||
|
class AdvancedBlendManager
|
||||||
|
{
|
||||||
|
private const int InstructionRamSize = 128;
|
||||||
|
private const int InstructionRamSizeMask = InstructionRamSize - 1;
|
||||||
|
|
||||||
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
||||||
|
|
||||||
|
private readonly uint[] _code;
|
||||||
|
private int _ip;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of the advanced blend manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state">GPU state of the channel owning this manager</param>
|
||||||
|
public AdvancedBlendManager(DeviceStateWithShadow<ThreedClassState> state)
|
||||||
|
{
|
||||||
|
_state = state;
|
||||||
|
_code = new uint[InstructionRamSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the start offset of the blend microcode in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
public void LoadBlendUcodeStart(int argument)
|
||||||
|
{
|
||||||
|
_ip = argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pushes one word of blend microcode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
public void LoadBlendUcodeInstruction(int argument)
|
||||||
|
{
|
||||||
|
_code[_ip++ & InstructionRamSizeMask] = (uint)argument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to identify the current advanced blend function being used,
|
||||||
|
/// given the current state and microcode that was uploaded.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="descriptor">Advanced blend descriptor</param>
|
||||||
|
/// <returns>True if the function was found, false otherwise</returns>
|
||||||
|
public bool TryGetAdvancedBlend(out AdvancedBlendDescriptor descriptor)
|
||||||
|
{
|
||||||
|
Span<uint> currentCode = new Span<uint>(_code);
|
||||||
|
byte codeLength = (byte)_state.State.BlendUcodeSize;
|
||||||
|
|
||||||
|
if (currentCode.Length > codeLength)
|
||||||
|
{
|
||||||
|
currentCode = currentCode.Slice(0, codeLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Hash128 hash = XXHash128.ComputeHash(MemoryMarshal.Cast<uint, byte>(currentCode));
|
||||||
|
|
||||||
|
descriptor = default;
|
||||||
|
|
||||||
|
if (!AdvancedBlendPreGenTable.Entries.TryGetValue(hash, out var entry))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Constants != null)
|
||||||
|
{
|
||||||
|
bool constantsMatch = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < entry.Constants.Length; i++)
|
||||||
|
{
|
||||||
|
RgbFloat constant = entry.Constants[i];
|
||||||
|
RgbHalf constant2 = _state.State.BlendUcodeConstants[i];
|
||||||
|
|
||||||
|
if ((Half)constant.R != constant2.UnpackR() ||
|
||||||
|
(Half)constant.G != constant2.UnpackG() ||
|
||||||
|
(Half)constant.B != constant2.UnpackB())
|
||||||
|
{
|
||||||
|
constantsMatch = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!constantsMatch)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Alpha.Enable != _state.State.BlendUcodeEnable)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Alpha.Enable == BlendUcodeEnable.EnableRGBA &&
|
||||||
|
(entry.Alpha.AlphaOp != _state.State.BlendStateCommon.AlphaOp ||
|
||||||
|
entry.Alpha.AlphaSrcFactor != _state.State.BlendStateCommon.AlphaSrcFactor ||
|
||||||
|
entry.Alpha.AlphaDstFactor != _state.State.BlendStateCommon.AlphaDstFactor))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor = new AdvancedBlendDescriptor(entry.Op, entry.Overlap, entry.SrcPreMultiplied);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,273 @@
|
||||||
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend function entry.
|
||||||
|
/// </summary>
|
||||||
|
struct AdvancedBlendEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend operation.
|
||||||
|
/// </summary>
|
||||||
|
public AdvancedBlendOp Op { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend overlap mode.
|
||||||
|
/// </summary>
|
||||||
|
public AdvancedBlendOverlap Overlap { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whenever the source input is pre-multiplied.
|
||||||
|
/// </summary>
|
||||||
|
public bool SrcPreMultiplied { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constants used by the microcode.
|
||||||
|
/// </summary>
|
||||||
|
public RgbFloat[] Constants { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fixed function alpha state.
|
||||||
|
/// </summary>
|
||||||
|
public FixedFunctionAlpha Alpha { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new advanced blend function entry.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="op">Advanced blend operation</param>
|
||||||
|
/// <param name="overlap">Advanced blend overlap mode</param>
|
||||||
|
/// <param name="srcPreMultiplied">Whenever the source input is pre-multiplied</param>
|
||||||
|
/// <param name="constants">Constants used by the microcode</param>
|
||||||
|
/// <param name="alpha">Fixed function alpha state</param>
|
||||||
|
public AdvancedBlendEntry(
|
||||||
|
AdvancedBlendOp op,
|
||||||
|
AdvancedBlendOverlap overlap,
|
||||||
|
bool srcPreMultiplied,
|
||||||
|
RgbFloat[] constants,
|
||||||
|
FixedFunctionAlpha alpha)
|
||||||
|
{
|
||||||
|
Op = op;
|
||||||
|
Overlap = overlap;
|
||||||
|
SrcPreMultiplied = srcPreMultiplied;
|
||||||
|
Constants = constants;
|
||||||
|
Alpha = alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pre-generated hash table with advanced blend functions used by the driver.
|
||||||
|
/// </summary>
|
||||||
|
static class AdvancedBlendPreGenTable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend functions dictionary.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly IReadOnlyDictionary<Hash128, AdvancedBlendEntry> Entries = new Dictionary<Hash128, AdvancedBlendEntry>()
|
||||||
|
{
|
||||||
|
{ new Hash128(0x19ECF57B83DE31F7, 0x5BAE759246F264C0), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xDE1B14A356A1A9ED, 0x59D803593C607C1D), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x1A3C3A6D32DEC368, 0xBCAE519EC6AAA045), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x6FD380261A63B240, 0x17C3B335DBB9E3DB), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x1D39164823D3A2D1, 0xC45350959CE1C8FB), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x18DF09FF53B129FE, 0xC02EDA33C36019F6), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x5973E583271EBF06, 0x711497D75D1272E0), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x4759E0E5DA54D5E8, 0x1FDD57C0C38AFA1F), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x337684D43CCE97FA, 0x0139E30CC529E1C9), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xDA59E85D8428992D, 0x1D3D7C64C9EF0132), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x9455B949298CE805, 0xE73D3301518BE98A), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xBDD3B4DEDBE336AA, 0xBFA4DCD50D535DEE), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x22D4E970A028649A, 0x4F3FCB055FCED965), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xA346A91311D72114, 0x151A27A3FB0A1904), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x8A307241061FACD6, 0xA39D1826440B8EE7), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xB3BE569485EFFFE0, 0x0BA4E269B3CFB165), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x36FCA3277DC11822, 0x2BC0F6CAC2029672), new AdvancedBlendEntry(AdvancedBlendOp.Contrast, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(2f, 2f, 2f), new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x4A6226AF2DE9BD7F, 0xEB890D7DA716F73A), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xF364CAA94E160FEB, 0xBF364512C72A3797), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x6BF791AB4AC19C87, 0x6FA17A994EA0FCDE), new AdvancedBlendEntry(AdvancedBlendOp.InvertOvg, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x053C75A0AE0BB222, 0x03C791FEEB59754C), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x25762AB40B6CBDE9, 0x595E9A968AC4F01C), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xC2D05E2DBE16955D, 0xB8659C7A3FCFA7CE), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x223F220B8F74CBFB, 0xD3DD19D7C39209A5), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xD0DAE57A9F1FE78A, 0x353796BCFB8CE30B), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x601C8CBEC07FF8FF, 0xB8E22882360E8695), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x3A55B7B78C76A7A8, 0x206F503B2D9FFEAA), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x80BC65C7831388E5, 0xC652457B2C766AEC), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x3D3A912E5833EE13, 0x307895951349EE33), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x289105BE92E81803, 0xFD8F1F03D15C53B4), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x007AE3BD140764EB, 0x0EE05A0D2E80BBAE), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x77F7EE0DB3FDDB96, 0xDEA47C881306DB3E), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x66F4E9A7D73CA157, 0x1486058A177DB11C), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Uncorrelated, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x593E9F331612D618, 0x9D217BEFA4EB919A), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x0A5194C5E6891106, 0xDD8EC6586106557C), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x8D77173D5E06E916, 0x06AB190E7D10F4D4), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x655B4EBC148981DA, 0x455999EF2B9BD28A), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x98F5437D5F518929, 0xBFF4A6E83183DB63), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x6ADDEFE3B9CEF2FD, 0xB6F6272AFECB1AAB), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x80953F0953BF05B1, 0xD59ABFAA34F8196F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xA401D9AA2A39C121, 0xFC0C8005C22AD7E3), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x06274FB7CA9CDD22, 0x6CE8188B1A9AB6EF), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x0B079BE7F7F70817, 0xB72E7736CA51E321), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x66215C99403CEDDE, 0x900B733D62204C48), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x12DEF2AD900CAD6C, 0x58CF5CC3004910DF), new AdvancedBlendEntry(AdvancedBlendOp.Plus, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x272BA3A49F64DAE4, 0xAC70B96C00A99EAF), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x206C34AAA7D3F545, 0xDA4B30CACAA483A0), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x3D93494920D257BE, 0xDCC573BE1F5F4449), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x0D7417D80191107B, 0xEAF40547827E005F), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xEC1B03E8C883F9C9, 0x2D3CA044C58C01B4), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x58A19A0135D68B31, 0x82F35B97AED068E5), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x20489F9AB36CC0E3, 0x20499874219E35EE), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xBB176935E5EE05BF, 0x95B26D4D30EA7A14), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x5FF9393C908ACFED, 0x068B0BD875773ABF), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x03181F8711C9802C, 0x6B02C7C6B224FE7B), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x2EE2209021F6B977, 0xF3AFA1491B8B89FC), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xD8BA4DD2EDE4DC9E, 0x01006114977CF715), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xD156B99835A2D8ED, 0x2D0BEE9E135EA7A7), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x20CE8C898ED4BE27, 0x1514900B6F5E8F66), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xCDE5F743820BA2D9, 0x917845FE2ECB083D), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xEB03DF4A0C1D14CD, 0xBAE2E831C6E8FFE4), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x1DC9E49AABC779AC, 0x4053A1441EB713D3), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xFBDEF776248F7B3E, 0xE05EEFD65AC47CB7), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x415A1A48E03AA6E7, 0x046D7EE33CA46B9A), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Disjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x59A6901EC9BB2041, 0x2F3E19CE5EEC3EBE), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x044B2B6E105221DA, 0x3089BBC033F994AF), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x374A5A24AA8E6CC5, 0x29930FAA6215FA2B), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x30CD0F7AF0CF26F9, 0x06CCA6744DE7DCF5), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Disjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x1A6C9A1F6FE494A5, 0xA0CFAF77617E54DD), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x081AF6DAAB1C8717, 0xBFEDCE59AE3DC9AC), new AdvancedBlendEntry(AdvancedBlendOp.Dst, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x3518E44573AB68BA, 0xC96EE71AF9F8F546), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xF89E81FE8D73C96F, 0x4583A04577A0F21C), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xDF4026421CB61119, 0x14115A1F5139AFC7), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x91A20262C3E3A695, 0x0B3A102BFCDC6B1C), new AdvancedBlendEntry(AdvancedBlendOp.DstIn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x44F4C7CCFEB9EBFA, 0xF68394E6D56E5C2F), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xB89F17C7021E9760, 0x430357EE0F7188EF), new AdvancedBlendEntry(AdvancedBlendOp.DstOut, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xDA2D20EA4242B8A0, 0x0D1EC05B72E3838F), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x855DFEE1208D11B9, 0x77C6E3DDCFE30B85), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x9B3808439683FD58, 0x123DCBE4705AB25E), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xA42CF045C248A00A, 0x0C6C63C24EA0B0C1), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x320A83B6D00C8059, 0x796EDAB3EB7314BC), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x45253AC9ABFFC613, 0x8F92EA70195FB573), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x1A5D263B588274B6, 0x167D305F6C794179), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x709C1A837FE966AC, 0x75D8CE49E8A78EDB), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x8265C26F85E4145F, 0x932E6CCBF37CB600), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x3F252B3FEF983F27, 0x9370D7EEFEFA1A9E), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x66A334A4AEA41078, 0xCB52254E1E395231), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xFDD05C53B25F0035, 0xB7E3ECEE166C222F), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x25D932A77FFED81A, 0xA50D797B0FCA94E8), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x4A953B6F5F7D341C, 0xDC05CFB50DDB5DC1), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x838CB660C4F41F6D, 0x9E7D958697543495), new AdvancedBlendEntry(AdvancedBlendOp.Invert, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x4DF6EC1348A8F797, 0xA128E0CD69DB5A64), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x178CDFAB9A015295, 0x2BF40EA72E596D57), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x338FC99050E56AFD, 0x2AF41CF82BE602BF), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x62E02ED60D1E978E, 0xBF726B3E68C11E4D), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xFBAF92DD4C101502, 0x7AF2EDA6596B819D), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x0EF1241F65D4B50A, 0xE8D85DFA6AEDDB84), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x77FE024B5C9D4A18, 0xF19D48A932F6860F), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Conjoint, true, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x9C88CBFA2E09D857, 0x0A0361704CBEEE1D), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x5B94127FA190E640, 0x8D1FEFF837A91268), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xB9C9105B7E063DDB, 0xF6A70E1D511B96FD), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xF0751AAE332B3ED1, 0xC40146F5C83C2533), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Conjoint, true, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x579EB12F595F75AD, 0x151BF0504703B81B), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xF9CA152C03AC8C62, 0x1581336205E5CF47), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.DstAlphaGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x98ACD8BB5E195D0F, 0x91F937672BE899F0), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0xBF97F10FC301F44C, 0x75721789F0D48548), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x1B982263B8B08A10, 0x3350C76E2E1B27DF), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0xFF20AC79F64EDED8, 0xAF9025B2D97B9273), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneMinusDstAlphaGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x9FFD986600FB112F, 0x384FDDF4E060139A), new AdvancedBlendEntry(AdvancedBlendOp.PlusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x0425E40B5B8B3B52, 0x5880CBED7CAB631C), new AdvancedBlendEntry(AdvancedBlendOp.PlusClampedAlpha, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x16DAC8593F28623A, 0x233DBC82325B8AED), new AdvancedBlendEntry(AdvancedBlendOp.PlusDarker, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xB37E5F234B9F0948, 0xD5F957A2ECD98FD6), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xCA0FDADD1D20DBE3, 0x1A5C15CCBF1AC538), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x1C48304D73A9DF3A, 0x891DB93FA36E3450), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x53200F2279B7FA39, 0x051C2462EBF6789C), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xB88BFB80714DCD5C, 0xEBD6938D744E6A41), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xE33DC2A25FC1A976, 0x08B3DBB1F3027D45), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xCE97E71615370316, 0xE131AE49D3A4D62B), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xE059FD265149B256, 0x94AF817AC348F61F), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x16D31333D477E231, 0x9A98AAC84F72CC62), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x47FC3B0776366D3C, 0xE96D9BD83B277874), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x7230401E3FEA1F3B, 0xF0D15F05D3D1E309), new AdvancedBlendEntry(AdvancedBlendOp.Minus, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.ReverseSubtractGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x188212F9303742F5, 0x100C51CB96E03591), new AdvancedBlendEntry(AdvancedBlendOp.MinusClamped, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x52B755D296B44DC5, 0x4003B87275625973), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xD873ED973ADF7EAD, 0x73E68B57D92034E7), new AdvancedBlendEntry(AdvancedBlendOp.Contrast, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(2f, 2f, 2f), new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x471F9FA34B945ACB, 0x10524D1410B3C402), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x99F569454EA0EF32, 0x6FC70A8B3A07DC8B), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x5AD55F950067AC7E, 0x4BA60A4FBABDD0AC), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x03FF2C858C9C4C5B, 0xE95AE7F561FB60E9), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x6DC0E510C7BCF9D2, 0xAE805D7CECDCB5C1), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x44832332CED5C054, 0x2F8D5536C085B30A), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x4AB4D387618AC51F, 0x495B46E0555F4B32), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x99282B49405A01A8, 0xD6FA93F864F24A8E), new AdvancedBlendEntry(AdvancedBlendOp.Red, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x37B30C1064FBD23E, 0x5D068366F42317C2), new AdvancedBlendEntry(AdvancedBlendOp.Green, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x760FAE9D59E04BC2, 0xA40AD483EA01435E), new AdvancedBlendEntry(AdvancedBlendOp.Blue, AdvancedBlendOverlap.Uncorrelated, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xE786950FD9D1C6EF, 0xF9FDD5AF6451D239), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x052458BB4788B0CA, 0x8AC58FDCA1F45EF5), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x6AFC3837D1D31920, 0xB9D49C2FE49642C6), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0xAFC2911949317E01, 0xD5B63636F5CB3422), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Uncorrelated, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneMinusSrcAlphaGl)) },
|
||||||
|
{ new Hash128(0x13B46DF507CC2C53, 0x86DE26517E6BF0A7), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x5C372442474BE410, 0x79ECD3C0C496EF2E), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x74AAB45DBF5336E9, 0x01BFC4E181DAD442), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x43239E282A36C85C, 0x36FB65560E46AD0F), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x1A3BA8A7583B8F7A, 0xE64E41D548033180), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x32BBB9859E9B565D, 0x3D5CE94FE55F18B5), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xD947A0766AE3C0FC, 0x391E5D53E86F4ED6), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0xBD9A7C08BDFD8CE6, 0x905407634901355E), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x8395475BCB0D7A8C, 0x48AF5DD501D44A70), new AdvancedBlendEntry(AdvancedBlendOp.Plus, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x80AAC23FEBD4A3E5, 0xEA8C70F0B4DE52DE), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x2F3AD1B0F1B3FD09, 0xC0EBC784BFAB8EA3), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x52B54032F2F70BFF, 0xC941D6FDED674765), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xCA7B86F72EC6A99B, 0x55868A131AFE359E), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x377919B60BD133CA, 0x0FD611627664EF40), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x9D4A0C5EE1153887, 0x7B869EBA218C589B), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x311F2A858545D123, 0xB4D09C802480AD62), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xCF78AA6A83AFA689, 0x9DC48B0C2182A3E1), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xC3018CD6F1CF62D1, 0x016E32DD9087B1BB), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x9CB62CE0E956EE29, 0x0FB67F503E60B3AD), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x3589A13C16EF3BFA, 0x15B29BFC91F3BDFB), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x3502CA5FB7529917, 0xFA51BFD0D1688071), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x62ADC25AD6D0A923, 0x76CB6D238276D3A3), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x09FDEB1116A9D52C, 0x85BB8627CD5C2733), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x0709FED1B65E18EB, 0x5BC3AA4D99EC19CF), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xB18D28AE5DE4C723, 0xE820AA2B75C9C02E), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x6743C51621497480, 0x4B164E40858834AE), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x63D1E181E34A2944, 0x1AE292C9D9F12819), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Disjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x079523298250BFF6, 0xC0C793510603CDB5), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x4C9D0A973C805EA6, 0xD1FF59AD5156B93C), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x1E914678F3057BCD, 0xD503AE389C12D229), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0x9FDBADE5556C5311, 0x03F0CBC798FC5C94), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Disjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xE39451534635403C, 0x606CC1CA1F452388), new AdvancedBlendEntry(AdvancedBlendOp.Src, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x1D39F0F0A1008AA6, 0xBFDF2B97E6C3F125), new AdvancedBlendEntry(AdvancedBlendOp.SrcOver, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xDB81BED30D5BDBEA, 0xAF0B2856EB93AD2C), new AdvancedBlendEntry(AdvancedBlendOp.DstOver, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x83F69CCF1D0A79B6, 0x70D31332797430AC), new AdvancedBlendEntry(AdvancedBlendOp.SrcIn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MinimumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x7B87F807AB7A8F5C, 0x1241A2A01FB31771), new AdvancedBlendEntry(AdvancedBlendOp.SrcOut, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xF557172E20D5272D, 0xC1961F8C7A5D2820), new AdvancedBlendEntry(AdvancedBlendOp.SrcAtop, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xA8476B3944DBBC9B, 0x84A2F6AF97B15FDF), new AdvancedBlendEntry(AdvancedBlendOp.DstAtop, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.OneGl, BlendFactor.ZeroGl)) },
|
||||||
|
{ new Hash128(0x3259602B55414DA3, 0x72AACCC00B5A9D10), new AdvancedBlendEntry(AdvancedBlendOp.Xor, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, 0, 0, 0)) },
|
||||||
|
{ new Hash128(0xC0CB8C10F36EDCD6, 0x8C2D088AD8191E1C), new AdvancedBlendEntry(AdvancedBlendOp.Multiply, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x81806C451C6255EF, 0x5AA8AC9A08941A15), new AdvancedBlendEntry(AdvancedBlendOp.Screen, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xE55A6537F4568198, 0xCA8735390B799B19), new AdvancedBlendEntry(AdvancedBlendOp.Overlay, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x5C044BA14536DDA3, 0xBCE0123ED7D510EC), new AdvancedBlendEntry(AdvancedBlendOp.Darken, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x6788346C405BE130, 0x372A4BB199C01F9F), new AdvancedBlendEntry(AdvancedBlendOp.Lighten, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x510EDC2A34E2856B, 0xE1727A407E294254), new AdvancedBlendEntry(AdvancedBlendOp.ColorDodge, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x4B7BE01BD398C7A8, 0x5BFF79BC00672C18), new AdvancedBlendEntry(AdvancedBlendOp.ColorBurn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x213B43845540CFEC, 0xDA857411CF1CCFCE), new AdvancedBlendEntry(AdvancedBlendOp.HardLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x765AFA6732E783F1, 0x8F1CABF1BC78A014), new AdvancedBlendEntry(AdvancedBlendOp.SoftLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.2605f, 0.2605f, 0.2605f), new RgbFloat(-0.7817f, -0.7817f, -0.7817f), new RgbFloat(0.3022f, 0.3022f, 0.3022f), new RgbFloat(0.2192f, 0.2192f, 0.2192f), new RgbFloat(0.25f, 0.25f, 0.25f), new RgbFloat(16f, 16f, 16f), new RgbFloat(12f, 12f, 12f), new RgbFloat(3f, 3f, 3f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xA4A5DE1CC06F6CB1, 0xA0634A0011001709), new AdvancedBlendEntry(AdvancedBlendOp.Difference, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x81F32BD8816EA796, 0x697EE86683165170), new AdvancedBlendEntry(AdvancedBlendOp.Exclusion, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xB870C209EAA5F092, 0xAF5FD923909CAA1F), new AdvancedBlendEntry(AdvancedBlendOp.InvertRGB, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.AddGl, BlendFactor.ZeroGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x3649A9F5C936FB83, 0xDD7C834897AA182A), new AdvancedBlendEntry(AdvancedBlendOp.LinearDodge, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xD72A2B1097A5995C, 0x3D41B2763A913654), new AdvancedBlendEntry(AdvancedBlendOp.LinearBurn, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x551E212B9F6C454A, 0xB0DFA05BEB3C37FA), new AdvancedBlendEntry(AdvancedBlendOp.VividLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.5f, 0.5f, 0.5f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x681B5A313B7416BF, 0xCB1CBAEEB4D81500), new AdvancedBlendEntry(AdvancedBlendOp.LinearLight, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(2f, 2f, 2f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x9343A18BD4B16777, 0xEDB4AC1C8972C3A4), new AdvancedBlendEntry(AdvancedBlendOp.PinLight, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xC960BF6D8519DE28, 0x78D8557FD405D119), new AdvancedBlendEntry(AdvancedBlendOp.HardMix, AdvancedBlendOverlap.Conjoint, false, Array.Empty<RgbFloat>(), new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x65A7B01FDC73A46C, 0x297E096ED5CC4D8A), new AdvancedBlendEntry(AdvancedBlendOp.HslHue, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0xD9C99BA4A6CDC13B, 0x3CFF0ACEDC2EE150), new AdvancedBlendEntry(AdvancedBlendOp.HslSaturation, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x6BC00DA6EB922BD1, 0x5FD4C11F2A685234), new AdvancedBlendEntry(AdvancedBlendOp.HslColor, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
{ new Hash128(0x8652300E32D93050, 0x9460E7B449132371), new AdvancedBlendEntry(AdvancedBlendOp.HslLuminosity, AdvancedBlendOverlap.Conjoint, false, new[] { new RgbFloat(0.3f, 0.59f, 0.11f) }, new FixedFunctionAlpha(BlendUcodeEnable.EnableRGB, BlendOp.MaximumGl, BlendFactor.OneGl, BlendFactor.OneGl)) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
126
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs
Normal file
126
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendUcode.cs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fixed function alpha state used for a advanced blend function.
|
||||||
|
/// </summary>
|
||||||
|
struct FixedFunctionAlpha
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Fixed function alpha state with alpha blending disabled.
|
||||||
|
/// </summary>
|
||||||
|
public static FixedFunctionAlpha Disabled => new FixedFunctionAlpha(BlendUcodeEnable.EnableRGBA, default, default, default);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Individual enable bits for the RGB and alpha components.
|
||||||
|
/// </summary>
|
||||||
|
public BlendUcodeEnable Enable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Alpha blend operation.
|
||||||
|
/// </summary>
|
||||||
|
public BlendOp AlphaOp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value multiplied with the blend source operand.
|
||||||
|
/// </summary>
|
||||||
|
public BlendFactor AlphaSrcFactor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value multiplied with the blend destination operand.
|
||||||
|
/// </summary>
|
||||||
|
public BlendFactor AlphaDstFactor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new blend fixed function alpha state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enable">Individual enable bits for the RGB and alpha components</param>
|
||||||
|
/// <param name="alphaOp">Alpha blend operation</param>
|
||||||
|
/// <param name="alphaSrc">Value multiplied with the blend source operand</param>
|
||||||
|
/// <param name="alphaDst">Value multiplied with the blend destination operand</param>
|
||||||
|
public FixedFunctionAlpha(BlendUcodeEnable enable, BlendOp alphaOp, BlendFactor alphaSrc, BlendFactor alphaDst)
|
||||||
|
{
|
||||||
|
Enable = enable;
|
||||||
|
AlphaOp = alphaOp;
|
||||||
|
AlphaSrcFactor = alphaSrc;
|
||||||
|
AlphaDstFactor = alphaDst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new blend fixed function alpha state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="alphaOp">Alpha blend operation</param>
|
||||||
|
/// <param name="alphaSrc">Value multiplied with the blend source operand</param>
|
||||||
|
/// <param name="alphaDst">Value multiplied with the blend destination operand</param>
|
||||||
|
public FixedFunctionAlpha(BlendOp alphaOp, BlendFactor alphaSrc, BlendFactor alphaDst) : this(BlendUcodeEnable.EnableRGB, alphaOp, alphaSrc, alphaDst)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode assembly function delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="asm">Assembler</param>
|
||||||
|
/// <returns>Fixed function alpha state for the microcode</returns>
|
||||||
|
delegate FixedFunctionAlpha GenUcodeFunc(ref UcodeAssembler asm);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend microcode state.
|
||||||
|
/// </summary>
|
||||||
|
struct AdvancedBlendUcode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend operation.
|
||||||
|
/// </summary>
|
||||||
|
public AdvancedBlendOp Op { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Advanced blend overlap mode.
|
||||||
|
/// </summary>
|
||||||
|
public AdvancedBlendOverlap Overlap { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whenever the source input is pre-multiplied.
|
||||||
|
/// </summary>
|
||||||
|
public bool SrcPreMultiplied { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fixed function alpha state.
|
||||||
|
/// </summary>
|
||||||
|
public FixedFunctionAlpha Alpha { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Microcode.
|
||||||
|
/// </summary>
|
||||||
|
public uint[] Code { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constants used by the microcode.
|
||||||
|
/// </summary>
|
||||||
|
public RgbFloat[] Constants { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new advanced blend state.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="op">Advanced blend operation</param>
|
||||||
|
/// <param name="overlap">Advanced blend overlap mode</param>
|
||||||
|
/// <param name="srcPreMultiplied">Whenever the source input is pre-multiplied</param>
|
||||||
|
/// <param name="genFunc">Function that will generate the advanced blend microcode</param>
|
||||||
|
public AdvancedBlendUcode(
|
||||||
|
AdvancedBlendOp op,
|
||||||
|
AdvancedBlendOverlap overlap,
|
||||||
|
bool srcPreMultiplied,
|
||||||
|
GenUcodeFunc genFunc)
|
||||||
|
{
|
||||||
|
Op = op;
|
||||||
|
Overlap = overlap;
|
||||||
|
SrcPreMultiplied = srcPreMultiplied;
|
||||||
|
|
||||||
|
UcodeAssembler asm = new UcodeAssembler();
|
||||||
|
Alpha = genFunc(ref asm);
|
||||||
|
Code = asm.GetCode();
|
||||||
|
Constants = asm.GetConstants();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
305
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs
Normal file
305
Ryujinx.Graphics.Gpu/Engine/Threed/Blender/UcodeAssembler.cs
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode instruction.
|
||||||
|
/// </summary>
|
||||||
|
enum Instruction
|
||||||
|
{
|
||||||
|
Mmadd = 0,
|
||||||
|
Mmsub = 1,
|
||||||
|
Min = 2,
|
||||||
|
Max = 3,
|
||||||
|
Rcp = 4,
|
||||||
|
Add = 5,
|
||||||
|
Sub = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode condition code.
|
||||||
|
/// </summary>
|
||||||
|
enum CC
|
||||||
|
{
|
||||||
|
F = 0,
|
||||||
|
T = 1,
|
||||||
|
EQ = 2,
|
||||||
|
NE = 3,
|
||||||
|
LT = 4,
|
||||||
|
LE = 5,
|
||||||
|
GT = 6,
|
||||||
|
GE = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode opend B or D value.
|
||||||
|
/// </summary>
|
||||||
|
enum OpBD
|
||||||
|
{
|
||||||
|
ConstantZero = 0x0,
|
||||||
|
ConstantOne = 0x1,
|
||||||
|
SrcRGB = 0x2,
|
||||||
|
SrcAAA = 0x3,
|
||||||
|
OneMinusSrcAAA = 0x4,
|
||||||
|
DstRGB = 0x5,
|
||||||
|
DstAAA = 0x6,
|
||||||
|
OneMinusDstAAA = 0x7,
|
||||||
|
Temp0 = 0x9,
|
||||||
|
Temp1 = 0xa,
|
||||||
|
Temp2 = 0xb,
|
||||||
|
PBR = 0xc,
|
||||||
|
ConstantRGB = 0xd
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode operand A or C value.
|
||||||
|
/// </summary>
|
||||||
|
enum OpAC
|
||||||
|
{
|
||||||
|
SrcRGB = 0,
|
||||||
|
DstRGB = 1,
|
||||||
|
SrcAAA = 2,
|
||||||
|
DstAAA = 3,
|
||||||
|
Temp0 = 4,
|
||||||
|
Temp1 = 5,
|
||||||
|
Temp2 = 6,
|
||||||
|
PBR = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode destination operand.
|
||||||
|
/// </summary>
|
||||||
|
enum OpDst
|
||||||
|
{
|
||||||
|
Temp0 = 0,
|
||||||
|
Temp1 = 1,
|
||||||
|
Temp2 = 2,
|
||||||
|
PBR = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode input swizzle.
|
||||||
|
/// </summary>
|
||||||
|
enum Swizzle
|
||||||
|
{
|
||||||
|
RGB = 0,
|
||||||
|
GBR = 1,
|
||||||
|
RRR = 2,
|
||||||
|
GGG = 3,
|
||||||
|
BBB = 4,
|
||||||
|
RToA = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode output components.
|
||||||
|
/// </summary>
|
||||||
|
enum WriteMask
|
||||||
|
{
|
||||||
|
RGB = 0,
|
||||||
|
R = 1,
|
||||||
|
G = 2,
|
||||||
|
B = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Floating-point RGB color values.
|
||||||
|
/// </summary>
|
||||||
|
struct RgbFloat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Red component value.
|
||||||
|
/// </summary>
|
||||||
|
public float R { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Green component value.
|
||||||
|
/// </summary>
|
||||||
|
public float G { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blue component value.
|
||||||
|
/// </summary>
|
||||||
|
public float B { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new floating-point RGB value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="r">Red component value</param>
|
||||||
|
/// <param name="g">Green component value</param>
|
||||||
|
/// <param name="b">Blue component value</param>
|
||||||
|
public RgbFloat(float r, float g, float b)
|
||||||
|
{
|
||||||
|
R = r;
|
||||||
|
G = g;
|
||||||
|
B = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode destination operand, including swizzle, write mask and condition code update flag.
|
||||||
|
/// </summary>
|
||||||
|
struct Dest
|
||||||
|
{
|
||||||
|
public static Dest Temp0 => new Dest(OpDst.Temp0, Swizzle.RGB, WriteMask.RGB, false);
|
||||||
|
public static Dest Temp1 => new Dest(OpDst.Temp1, Swizzle.RGB, WriteMask.RGB, false);
|
||||||
|
public static Dest Temp2 => new Dest(OpDst.Temp2, Swizzle.RGB, WriteMask.RGB, false);
|
||||||
|
public static Dest PBR => new Dest(OpDst.PBR, Swizzle.RGB, WriteMask.RGB, false);
|
||||||
|
|
||||||
|
public Dest GBR => new Dest(Dst, Swizzle.GBR, WriteMask, WriteCC);
|
||||||
|
public Dest RRR => new Dest(Dst, Swizzle.RRR, WriteMask, WriteCC);
|
||||||
|
public Dest GGG => new Dest(Dst, Swizzle.GGG, WriteMask, WriteCC);
|
||||||
|
public Dest BBB => new Dest(Dst, Swizzle.BBB, WriteMask, WriteCC);
|
||||||
|
public Dest RToA => new Dest(Dst, Swizzle.RToA, WriteMask, WriteCC);
|
||||||
|
|
||||||
|
public Dest R => new Dest(Dst, Swizzle, WriteMask.R, WriteCC);
|
||||||
|
public Dest G => new Dest(Dst, Swizzle, WriteMask.G, WriteCC);
|
||||||
|
public Dest B => new Dest(Dst, Swizzle, WriteMask.B, WriteCC);
|
||||||
|
|
||||||
|
public Dest CC => new Dest(Dst, Swizzle, WriteMask, true);
|
||||||
|
|
||||||
|
public OpDst Dst { get; }
|
||||||
|
public Swizzle Swizzle { get; }
|
||||||
|
public WriteMask WriteMask { get; }
|
||||||
|
public bool WriteCC { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new blend microcode destination operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dst">Operand</param>
|
||||||
|
/// <param name="swizzle">Swizzle</param>
|
||||||
|
/// <param name="writeMask">Write maks</param>
|
||||||
|
/// <param name="writeCC">Indicates if condition codes should be updated</param>
|
||||||
|
public Dest(OpDst dst, Swizzle swizzle, WriteMask writeMask, bool writeCC)
|
||||||
|
{
|
||||||
|
Dst = dst;
|
||||||
|
Swizzle = swizzle;
|
||||||
|
WriteMask = writeMask;
|
||||||
|
WriteCC = writeCC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode operaiton.
|
||||||
|
/// </summary>
|
||||||
|
struct UcodeOp
|
||||||
|
{
|
||||||
|
public readonly uint Word;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new blend microcode operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cc">Condition code that controls whenever the operation is executed or not</param>
|
||||||
|
/// <param name="inst">Instruction</param>
|
||||||
|
/// <param name="constIndex">Index on the constant table of the constant used by any constant operand</param>
|
||||||
|
/// <param name="dest">Destination operand</param>
|
||||||
|
/// <param name="srcA">First input operand</param>
|
||||||
|
/// <param name="srcB">Second input operand</param>
|
||||||
|
/// <param name="srcC">Third input operand</param>
|
||||||
|
/// <param name="srcD">Fourth input operand</param>
|
||||||
|
public UcodeOp(CC cc, Instruction inst, int constIndex, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
|
||||||
|
{
|
||||||
|
Word = (uint)cc |
|
||||||
|
((uint)inst << 3) |
|
||||||
|
((uint)constIndex << 6) |
|
||||||
|
((uint)srcA << 9) |
|
||||||
|
((uint)srcB << 12) |
|
||||||
|
((uint)srcC << 16) |
|
||||||
|
((uint)srcD << 19) |
|
||||||
|
((uint)dest.Swizzle << 23) |
|
||||||
|
((uint)dest.WriteMask << 26) |
|
||||||
|
((uint)dest.Dst << 28) |
|
||||||
|
(dest.WriteCC ? (1u << 31) : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blend microcode assembler.
|
||||||
|
/// </summary>
|
||||||
|
struct UcodeAssembler
|
||||||
|
{
|
||||||
|
private List<uint> _code;
|
||||||
|
private RgbFloat[] _constants;
|
||||||
|
private int _constantIndex;
|
||||||
|
|
||||||
|
public void Mul(CC cc, Dest dest, OpAC srcA, OpBD srcB)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Madd(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, srcC, OpBD.ConstantOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Mmadd(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Mmadd, dest, srcA, srcB, srcC, srcD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Mmsub(CC cc, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Mmsub, dest, srcA, srcB, srcC, srcD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Min(CC cc, Dest dest, OpAC srcA, OpBD srcB)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Min, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Max(CC cc, Dest dest, OpAC srcA, OpBD srcB)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Max, dest, srcA, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Rcp(CC cc, Dest dest, OpAC srcA)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Rcp, dest, srcA, OpBD.ConstantZero, OpAC.SrcRGB, OpBD.ConstantZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Mov(CC cc, Dest dest, OpBD srcB)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Add, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, OpBD.ConstantZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(CC cc, Dest dest, OpBD srcB, OpBD srcD)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Add, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, srcD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Sub(CC cc, Dest dest, OpBD srcB, OpBD srcD)
|
||||||
|
{
|
||||||
|
Assemble(cc, Instruction.Sub, dest, OpAC.SrcRGB, srcB, OpAC.SrcRGB, srcD);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Assemble(CC cc, Instruction inst, Dest dest, OpAC srcA, OpBD srcB, OpAC srcC, OpBD srcD)
|
||||||
|
{
|
||||||
|
(_code ??= new List<uint>()).Add(new UcodeOp(cc, inst, _constantIndex, dest, srcA, srcB, srcC, srcD).Word);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetConstant(int index, float r, float g, float b)
|
||||||
|
{
|
||||||
|
if (_constants == null)
|
||||||
|
{
|
||||||
|
_constants = new RgbFloat[index + 1];
|
||||||
|
}
|
||||||
|
else if (_constants.Length <= index)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _constants, index + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_constants[index] = new RgbFloat(r, g, b);
|
||||||
|
_constantIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint[] GetCode()
|
||||||
|
{
|
||||||
|
return _code?.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RgbFloat[] GetConstants()
|
||||||
|
{
|
||||||
|
return _constants;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Ryujinx.Graphics.Gpu.Engine.Threed.Blender;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.Types;
|
using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
using Ryujinx.Graphics.Gpu.Shader;
|
using Ryujinx.Graphics.Gpu.Shader;
|
||||||
|
@ -26,6 +27,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
private readonly GpuChannel _channel;
|
private readonly GpuChannel _channel;
|
||||||
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
||||||
private readonly DrawState _drawState;
|
private readonly DrawState _drawState;
|
||||||
|
private readonly AdvancedBlendManager _blendManager;
|
||||||
|
|
||||||
private readonly StateUpdateTracker<ThreedClassState> _updateTracker;
|
private readonly StateUpdateTracker<ThreedClassState> _updateTracker;
|
||||||
|
|
||||||
|
@ -55,13 +57,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
/// <param name="channel">GPU channel</param>
|
/// <param name="channel">GPU channel</param>
|
||||||
/// <param name="state">3D engine state</param>
|
/// <param name="state">3D engine state</param>
|
||||||
/// <param name="drawState">Draw state</param>
|
/// <param name="drawState">Draw state</param>
|
||||||
|
/// <param name="blendManager">Advanced blend manager</param>
|
||||||
/// <param name="spec">Specialization state updater</param>
|
/// <param name="spec">Specialization state updater</param>
|
||||||
public StateUpdater(GpuContext context, GpuChannel channel, DeviceStateWithShadow<ThreedClassState> state, DrawState drawState, SpecializationStateUpdater spec)
|
public StateUpdater(
|
||||||
|
GpuContext context,
|
||||||
|
GpuChannel channel,
|
||||||
|
DeviceStateWithShadow<ThreedClassState> state,
|
||||||
|
DrawState drawState,
|
||||||
|
AdvancedBlendManager blendManager,
|
||||||
|
SpecializationStateUpdater spec)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
_drawState = drawState;
|
_drawState = drawState;
|
||||||
|
_blendManager = blendManager;
|
||||||
_currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages];
|
_currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages];
|
||||||
_currentSpecState = spec;
|
_currentSpecState = spec;
|
||||||
|
|
||||||
|
@ -84,6 +94,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
new StateUpdateCallbackEntry(UpdateVertexAttribState, nameof(ThreedClassState.VertexAttribState)),
|
new StateUpdateCallbackEntry(UpdateVertexAttribState, nameof(ThreedClassState.VertexAttribState)),
|
||||||
|
|
||||||
new StateUpdateCallbackEntry(UpdateBlendState,
|
new StateUpdateCallbackEntry(UpdateBlendState,
|
||||||
|
nameof(ThreedClassState.BlendUcodeEnable),
|
||||||
|
nameof(ThreedClassState.BlendUcodeSize),
|
||||||
nameof(ThreedClassState.BlendIndependent),
|
nameof(ThreedClassState.BlendIndependent),
|
||||||
nameof(ThreedClassState.BlendConstant),
|
nameof(ThreedClassState.BlendConstant),
|
||||||
nameof(ThreedClassState.BlendStateCommon),
|
nameof(ThreedClassState.BlendStateCommon),
|
||||||
|
@ -1154,6 +1166,20 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void UpdateBlendState()
|
private void UpdateBlendState()
|
||||||
{
|
{
|
||||||
|
if (_state.State.BlendUcodeEnable != BlendUcodeEnable.Disabled)
|
||||||
|
{
|
||||||
|
if (_context.Capabilities.SupportsBlendEquationAdvanced && _blendManager.TryGetAdvancedBlend(out var blendDescriptor))
|
||||||
|
{
|
||||||
|
// Try to HLE it using advanced blend on the host if we can.
|
||||||
|
_context.Renderer.Pipeline.SetBlendState(blendDescriptor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Blend emulation fallback.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool blendIndependent = _state.State.BlendIndependent;
|
bool blendIndependent = _state.State.BlendIndependent;
|
||||||
ColorF blendConstant = _state.State.BlendConstant;
|
ColorF blendConstant = _state.State.BlendConstant;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
|
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
|
||||||
|
using Ryujinx.Graphics.Gpu.Engine.Threed.Blender;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
@ -18,6 +19,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
private readonly DeviceStateWithShadow<ThreedClassState> _state;
|
||||||
|
|
||||||
private readonly InlineToMemoryClass _i2mClass;
|
private readonly InlineToMemoryClass _i2mClass;
|
||||||
|
private readonly AdvancedBlendManager _blendManager;
|
||||||
private readonly DrawManager _drawManager;
|
private readonly DrawManager _drawManager;
|
||||||
private readonly SemaphoreUpdater _semaphoreUpdater;
|
private readonly SemaphoreUpdater _semaphoreUpdater;
|
||||||
private readonly ConstantBufferUpdater _cbUpdater;
|
private readonly ConstantBufferUpdater _cbUpdater;
|
||||||
|
@ -40,6 +42,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
{ nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) },
|
{ nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) },
|
||||||
{ nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) },
|
{ nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) },
|
||||||
{ nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) },
|
{ nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) },
|
||||||
|
{ nameof(ThreedClassState.LoadBlendUcodeStart), new RwCallback(LoadBlendUcodeStart, null) },
|
||||||
|
{ nameof(ThreedClassState.LoadBlendUcodeInstruction), new RwCallback(LoadBlendUcodeInstruction, null) },
|
||||||
{ nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) },
|
{ nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) },
|
||||||
{ nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) },
|
{ nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) },
|
||||||
{ nameof(ThreedClassState.DrawVertexArrayBeginEndInstanceFirst), new RwCallback(DrawVertexArrayBeginEndInstanceFirst, null) },
|
{ nameof(ThreedClassState.DrawVertexArrayBeginEndInstanceFirst), new RwCallback(DrawVertexArrayBeginEndInstanceFirst, null) },
|
||||||
|
@ -75,9 +79,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
var drawState = new DrawState();
|
var drawState = new DrawState();
|
||||||
|
|
||||||
_drawManager = new DrawManager(context, channel, _state, drawState, spec);
|
_drawManager = new DrawManager(context, channel, _state, drawState, spec);
|
||||||
|
_blendManager = new AdvancedBlendManager(_state);
|
||||||
_semaphoreUpdater = new SemaphoreUpdater(context, channel, _state);
|
_semaphoreUpdater = new SemaphoreUpdater(context, channel, _state);
|
||||||
_cbUpdater = new ConstantBufferUpdater(channel, _state);
|
_cbUpdater = new ConstantBufferUpdater(channel, _state);
|
||||||
_stateUpdater = new StateUpdater(context, channel, _state, drawState, spec);
|
_stateUpdater = new StateUpdater(context, channel, _state, drawState, _blendManager, spec);
|
||||||
|
|
||||||
// This defaults to "always", even without any register write.
|
// This defaults to "always", even without any register write.
|
||||||
// Reads just return 0, regardless of what was set there.
|
// Reads just return 0, regardless of what was set there.
|
||||||
|
@ -283,6 +288,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
_context.Renderer.Pipeline.TextureBarrier();
|
_context.Renderer.Pipeline.TextureBarrier();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the start offset of the blend microcode in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
private void LoadBlendUcodeStart(int argument)
|
||||||
|
{
|
||||||
|
_blendManager.LoadBlendUcodeStart(argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pushes one word of blend microcode.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
private void LoadBlendUcodeInstruction(int argument)
|
||||||
|
{
|
||||||
|
_blendManager.LoadBlendUcodeInstruction(argument);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Issues a texture barrier.
|
/// Issues a texture barrier.
|
||||||
/// This waits until previous texture writes from the GPU to finish, before
|
/// This waits until previous texture writes from the GPU to finish, before
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Ryujinx.Graphics.Gpu.Engine.Types;
|
||||||
using Ryujinx.Graphics.Gpu.Image;
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
{
|
{
|
||||||
|
@ -214,6 +215,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
#pragma warning restore CS0649
|
#pragma warning restore CS0649
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whenever the blend microcode processes RGB and alpha components.
|
||||||
|
/// </summary>
|
||||||
|
enum BlendUcodeEnable
|
||||||
|
{
|
||||||
|
Disabled = 0,
|
||||||
|
EnableRGB = 1,
|
||||||
|
EnableAlpha = 2,
|
||||||
|
EnableRGBA = 3
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scissor state.
|
/// Scissor state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -434,6 +446,49 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
TriangleRastFlip = 1 << 4
|
TriangleRastFlip = 1 << 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// RGB color components packed as 16-bit float values.
|
||||||
|
/// </summary>
|
||||||
|
struct RgbHalf
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
public uint R;
|
||||||
|
public uint G;
|
||||||
|
public uint B;
|
||||||
|
public uint Padding;
|
||||||
|
#pragma warning restore CS0649
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the red color component as a 16-bit float value.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The component value</returns>
|
||||||
|
public Half UnpackR()
|
||||||
|
{
|
||||||
|
ushort value = (ushort)R;
|
||||||
|
return Unsafe.As<ushort, Half>(ref value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the green color component as a 16-bit float value.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The component value</returns>
|
||||||
|
public Half UnpackG()
|
||||||
|
{
|
||||||
|
ushort value = (ushort)G;
|
||||||
|
return Unsafe.As<ushort, Half>(ref value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the blue color component as a 16-bit float value.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The component value</returns>
|
||||||
|
public Half UnpackB()
|
||||||
|
{
|
||||||
|
ushort value = (ushort)B;
|
||||||
|
return Unsafe.As<ushort, Half>(ref value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Condition for conditional rendering.
|
/// Condition for conditional rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -752,7 +807,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
public Boolean32 EarlyZForce;
|
public Boolean32 EarlyZForce;
|
||||||
public fixed uint Reserved214[45];
|
public fixed uint Reserved214[45];
|
||||||
public uint SyncpointAction;
|
public uint SyncpointAction;
|
||||||
public fixed uint Reserved2CC[21];
|
public fixed uint Reserved2CC[10];
|
||||||
|
public uint BlendUcodeNormalizedDst;
|
||||||
|
public fixed uint Reserved2F8[10];
|
||||||
public TessMode TessMode;
|
public TessMode TessMode;
|
||||||
public Array4<float> TessOuterLevel;
|
public Array4<float> TessOuterLevel;
|
||||||
public Array2<float> TessInnerLevel;
|
public Array2<float> TessInnerLevel;
|
||||||
|
@ -781,11 +838,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
public fixed uint ReservedDB8[2];
|
public fixed uint ReservedDB8[2];
|
||||||
public DepthBiasState DepthBiasState;
|
public DepthBiasState DepthBiasState;
|
||||||
public int PatchVertices;
|
public int PatchVertices;
|
||||||
public fixed uint ReservedDD0[4];
|
public BlendUcodeEnable BlendUcodeEnable;
|
||||||
|
public uint BlendUcodeSize;
|
||||||
|
public fixed uint ReservedDD8[2];
|
||||||
public uint TextureBarrier;
|
public uint TextureBarrier;
|
||||||
public uint WatchdogTimer;
|
public uint WatchdogTimer;
|
||||||
public Boolean32 PrimitiveRestartDrawArrays;
|
public Boolean32 PrimitiveRestartDrawArrays;
|
||||||
public fixed uint ReservedDEC[5];
|
public uint ReservedDEC;
|
||||||
|
public uint LoadBlendUcodeStart;
|
||||||
|
public uint LoadBlendUcodeInstruction;
|
||||||
|
public fixed uint ReservedDF8[2];
|
||||||
public Array16<ScissorState> ScissorState;
|
public Array16<ScissorState> ScissorState;
|
||||||
public fixed uint ReservedF00[21];
|
public fixed uint ReservedF00[21];
|
||||||
public StencilBackMasks StencilBackMasks;
|
public StencilBackMasks StencilBackMasks;
|
||||||
|
@ -850,7 +912,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
public fixed uint Reserved142C[2];
|
public fixed uint Reserved142C[2];
|
||||||
public uint FirstVertex;
|
public uint FirstVertex;
|
||||||
public uint FirstInstance;
|
public uint FirstInstance;
|
||||||
public fixed uint Reserved143C[53];
|
public fixed uint Reserved143C[17];
|
||||||
|
public Array8<RgbHalf> BlendUcodeConstants;
|
||||||
|
public fixed uint Reserved1500[4];
|
||||||
public uint ClipDistanceEnable;
|
public uint ClipDistanceEnable;
|
||||||
public uint Reserved1514;
|
public uint Reserved1514;
|
||||||
public float PointSize;
|
public float PointSize;
|
||||||
|
|
|
@ -34,6 +34,126 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return TextureWrapMode.Clamp;
|
return TextureWrapMode.Clamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NvBlendEquationAdvanced Convert(this AdvancedBlendOp op)
|
||||||
|
{
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case AdvancedBlendOp.Zero:
|
||||||
|
return NvBlendEquationAdvanced.Zero;
|
||||||
|
case AdvancedBlendOp.Src:
|
||||||
|
return NvBlendEquationAdvanced.SrcNv;
|
||||||
|
case AdvancedBlendOp.Dst:
|
||||||
|
return NvBlendEquationAdvanced.DstNv;
|
||||||
|
case AdvancedBlendOp.SrcOver:
|
||||||
|
return NvBlendEquationAdvanced.SrcOverNv;
|
||||||
|
case AdvancedBlendOp.DstOver:
|
||||||
|
return NvBlendEquationAdvanced.DstOverNv;
|
||||||
|
case AdvancedBlendOp.SrcIn:
|
||||||
|
return NvBlendEquationAdvanced.SrcInNv;
|
||||||
|
case AdvancedBlendOp.DstIn:
|
||||||
|
return NvBlendEquationAdvanced.DstInNv;
|
||||||
|
case AdvancedBlendOp.SrcOut:
|
||||||
|
return NvBlendEquationAdvanced.SrcOutNv;
|
||||||
|
case AdvancedBlendOp.DstOut:
|
||||||
|
return NvBlendEquationAdvanced.DstOutNv;
|
||||||
|
case AdvancedBlendOp.SrcAtop:
|
||||||
|
return NvBlendEquationAdvanced.SrcAtopNv;
|
||||||
|
case AdvancedBlendOp.DstAtop:
|
||||||
|
return NvBlendEquationAdvanced.DstAtopNv;
|
||||||
|
case AdvancedBlendOp.Xor:
|
||||||
|
return NvBlendEquationAdvanced.XorNv;
|
||||||
|
case AdvancedBlendOp.Plus:
|
||||||
|
return NvBlendEquationAdvanced.PlusNv;
|
||||||
|
case AdvancedBlendOp.PlusClamped:
|
||||||
|
return NvBlendEquationAdvanced.PlusClampedNv;
|
||||||
|
case AdvancedBlendOp.PlusClampedAlpha:
|
||||||
|
return NvBlendEquationAdvanced.PlusClampedAlphaNv;
|
||||||
|
case AdvancedBlendOp.PlusDarker:
|
||||||
|
return NvBlendEquationAdvanced.PlusDarkerNv;
|
||||||
|
case AdvancedBlendOp.Multiply:
|
||||||
|
return NvBlendEquationAdvanced.MultiplyNv;
|
||||||
|
case AdvancedBlendOp.Screen:
|
||||||
|
return NvBlendEquationAdvanced.ScreenNv;
|
||||||
|
case AdvancedBlendOp.Overlay:
|
||||||
|
return NvBlendEquationAdvanced.OverlayNv;
|
||||||
|
case AdvancedBlendOp.Darken:
|
||||||
|
return NvBlendEquationAdvanced.DarkenNv;
|
||||||
|
case AdvancedBlendOp.Lighten:
|
||||||
|
return NvBlendEquationAdvanced.LightenNv;
|
||||||
|
case AdvancedBlendOp.ColorDodge:
|
||||||
|
return NvBlendEquationAdvanced.ColordodgeNv;
|
||||||
|
case AdvancedBlendOp.ColorBurn:
|
||||||
|
return NvBlendEquationAdvanced.ColorburnNv;
|
||||||
|
case AdvancedBlendOp.HardLight:
|
||||||
|
return NvBlendEquationAdvanced.HardlightNv;
|
||||||
|
case AdvancedBlendOp.SoftLight:
|
||||||
|
return NvBlendEquationAdvanced.SoftlightNv;
|
||||||
|
case AdvancedBlendOp.Difference:
|
||||||
|
return NvBlendEquationAdvanced.DifferenceNv;
|
||||||
|
case AdvancedBlendOp.Minus:
|
||||||
|
return NvBlendEquationAdvanced.MinusNv;
|
||||||
|
case AdvancedBlendOp.MinusClamped:
|
||||||
|
return NvBlendEquationAdvanced.MinusClampedNv;
|
||||||
|
case AdvancedBlendOp.Exclusion:
|
||||||
|
return NvBlendEquationAdvanced.ExclusionNv;
|
||||||
|
case AdvancedBlendOp.Contrast:
|
||||||
|
return NvBlendEquationAdvanced.ContrastNv;
|
||||||
|
case AdvancedBlendOp.Invert:
|
||||||
|
return NvBlendEquationAdvanced.Invert;
|
||||||
|
case AdvancedBlendOp.InvertRGB:
|
||||||
|
return NvBlendEquationAdvanced.InvertRgbNv;
|
||||||
|
case AdvancedBlendOp.InvertOvg:
|
||||||
|
return NvBlendEquationAdvanced.InvertOvgNv;
|
||||||
|
case AdvancedBlendOp.LinearDodge:
|
||||||
|
return NvBlendEquationAdvanced.LineardodgeNv;
|
||||||
|
case AdvancedBlendOp.LinearBurn:
|
||||||
|
return NvBlendEquationAdvanced.LinearburnNv;
|
||||||
|
case AdvancedBlendOp.VividLight:
|
||||||
|
return NvBlendEquationAdvanced.VividlightNv;
|
||||||
|
case AdvancedBlendOp.LinearLight:
|
||||||
|
return NvBlendEquationAdvanced.LinearlightNv;
|
||||||
|
case AdvancedBlendOp.PinLight:
|
||||||
|
return NvBlendEquationAdvanced.PinlightNv;
|
||||||
|
case AdvancedBlendOp.HardMix:
|
||||||
|
return NvBlendEquationAdvanced.HardmixNv;
|
||||||
|
case AdvancedBlendOp.Red:
|
||||||
|
return NvBlendEquationAdvanced.RedNv;
|
||||||
|
case AdvancedBlendOp.Green:
|
||||||
|
return NvBlendEquationAdvanced.GreenNv;
|
||||||
|
case AdvancedBlendOp.Blue:
|
||||||
|
return NvBlendEquationAdvanced.BlueNv;
|
||||||
|
case AdvancedBlendOp.HslHue:
|
||||||
|
return NvBlendEquationAdvanced.HslHueNv;
|
||||||
|
case AdvancedBlendOp.HslSaturation:
|
||||||
|
return NvBlendEquationAdvanced.HslSaturationNv;
|
||||||
|
case AdvancedBlendOp.HslColor:
|
||||||
|
return NvBlendEquationAdvanced.HslColorNv;
|
||||||
|
case AdvancedBlendOp.HslLuminosity:
|
||||||
|
return NvBlendEquationAdvanced.HslLuminosityNv;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOp)} enum value: {op}.");
|
||||||
|
|
||||||
|
return NvBlendEquationAdvanced.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static All Convert(this AdvancedBlendOverlap overlap)
|
||||||
|
{
|
||||||
|
switch (overlap)
|
||||||
|
{
|
||||||
|
case AdvancedBlendOverlap.Uncorrelated:
|
||||||
|
return All.UncorrelatedNv;
|
||||||
|
case AdvancedBlendOverlap.Disjoint:
|
||||||
|
return All.DisjointNv;
|
||||||
|
case AdvancedBlendOverlap.Conjoint:
|
||||||
|
return All.ConjointNv;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOverlap)} enum value: {overlap}.");
|
||||||
|
|
||||||
|
return All.UncorrelatedNv;
|
||||||
|
}
|
||||||
|
|
||||||
public static All Convert(this BlendFactor factor)
|
public static All Convert(this BlendFactor factor)
|
||||||
{
|
{
|
||||||
switch (factor)
|
switch (factor)
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
|
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
|
||||||
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
||||||
|
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced"));
|
||||||
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
|
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
|
||||||
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
|
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
|
||||||
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
|
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
|
||||||
|
@ -51,6 +52,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
|
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
|
||||||
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
||||||
|
public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
|
||||||
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
|
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
|
||||||
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
|
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
|
||||||
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
|
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
|
||||||
|
|
|
@ -119,6 +119,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
supportsR4G4B4A4Format: true,
|
supportsR4G4B4A4Format: true,
|
||||||
supportsSnormBufferTextureFormat: false,
|
supportsSnormBufferTextureFormat: false,
|
||||||
supports5BitComponentFormat: true,
|
supports5BitComponentFormat: true,
|
||||||
|
supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
|
||||||
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
private uint _fragmentOutputMap;
|
private uint _fragmentOutputMap;
|
||||||
private uint _componentMasks;
|
private uint _componentMasks;
|
||||||
private uint _currentComponentMasks;
|
private uint _currentComponentMasks;
|
||||||
|
private bool _advancedBlendEnable;
|
||||||
|
|
||||||
private uint _scissorEnables;
|
private uint _scissorEnables;
|
||||||
|
|
||||||
|
@ -784,8 +785,26 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
GL.Enable(EnableCap.AlphaTest);
|
GL.Enable(EnableCap.AlphaTest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBlendState(AdvancedBlendDescriptor blend)
|
||||||
|
{
|
||||||
|
if (HwCapabilities.SupportsBlendEquationAdvanced)
|
||||||
|
{
|
||||||
|
GL.BlendEquation((BlendEquationMode)blend.Op.Convert());
|
||||||
|
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendOverlapNv, (int)blend.Overlap.Convert());
|
||||||
|
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendPremultipliedSrcNv, blend.SrcPreMultiplied ? 1 : 0);
|
||||||
|
GL.Enable(EnableCap.Blend);
|
||||||
|
_advancedBlendEnable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetBlendState(int index, BlendDescriptor blend)
|
public void SetBlendState(int index, BlendDescriptor blend)
|
||||||
{
|
{
|
||||||
|
if (_advancedBlendEnable)
|
||||||
|
{
|
||||||
|
GL.Disable(EnableCap.Blend);
|
||||||
|
_advancedBlendEnable = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!blend.Enable)
|
if (!blend.Enable)
|
||||||
{
|
{
|
||||||
GL.Disable(IndexedEnableCap.Blend, index);
|
GL.Disable(IndexedEnableCap.Blend, index);
|
||||||
|
|
|
@ -79,6 +79,60 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.AdvancedBlendOp op)
|
||||||
|
{
|
||||||
|
return op switch
|
||||||
|
{
|
||||||
|
GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
|
||||||
|
GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
|
||||||
|
GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
|
||||||
|
GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
|
||||||
|
GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
|
||||||
|
GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
|
||||||
|
GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
|
||||||
|
GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
|
||||||
|
GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
|
||||||
|
GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
|
||||||
|
GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
|
||||||
|
GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
|
||||||
|
GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
|
||||||
|
GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
|
||||||
|
GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
|
||||||
|
GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
|
||||||
|
GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
|
||||||
|
GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
|
||||||
|
GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
|
||||||
|
GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
|
||||||
|
GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
|
||||||
|
GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
|
||||||
|
GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
|
||||||
|
GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
|
||||||
|
GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
|
||||||
|
GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
|
||||||
|
GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
|
||||||
|
GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
|
||||||
|
GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
|
||||||
|
GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
|
||||||
|
GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
|
||||||
|
GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
|
||||||
|
GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
|
||||||
|
GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
|
||||||
|
GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
|
||||||
|
GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
|
||||||
|
GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
|
||||||
|
GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
|
||||||
|
GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
|
||||||
|
GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
|
||||||
|
GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
|
||||||
|
GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
|
||||||
|
GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
|
||||||
|
GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
|
||||||
|
GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
|
||||||
|
GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
|
||||||
|
_ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
|
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
|
@ -92,6 +146,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Silk.NET.Vulkan.BlendOverlapEXT Convert(this GAL.AdvancedBlendOverlap overlap)
|
||||||
|
{
|
||||||
|
return overlap switch
|
||||||
|
{
|
||||||
|
GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
|
||||||
|
GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
|
||||||
|
GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
|
||||||
|
_ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
|
public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
|
|
|
@ -18,6 +18,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
public readonly bool SupportsIndexTypeUint8;
|
public readonly bool SupportsIndexTypeUint8;
|
||||||
public readonly bool SupportsCustomBorderColor;
|
public readonly bool SupportsCustomBorderColor;
|
||||||
|
public readonly bool SupportsBlendEquationAdvanced;
|
||||||
|
public readonly bool SupportsBlendEquationAdvancedCorrelatedOverlap;
|
||||||
|
public readonly bool SupportsBlendEquationAdvancedNonPreMultipliedSrcColor;
|
||||||
|
public readonly bool SupportsBlendEquationAdvancedNonPreMultipliedDstColor;
|
||||||
public readonly bool SupportsIndirectParameters;
|
public readonly bool SupportsIndirectParameters;
|
||||||
public readonly bool SupportsFragmentShaderInterlock;
|
public readonly bool SupportsFragmentShaderInterlock;
|
||||||
public readonly bool SupportsGeometryShaderPassthrough;
|
public readonly bool SupportsGeometryShaderPassthrough;
|
||||||
|
@ -44,6 +48,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public HardwareCapabilities(
|
public HardwareCapabilities(
|
||||||
bool supportsIndexTypeUint8,
|
bool supportsIndexTypeUint8,
|
||||||
bool supportsCustomBorderColor,
|
bool supportsCustomBorderColor,
|
||||||
|
bool supportsBlendEquationAdvanced,
|
||||||
|
bool supportsBlendEquationAdvancedCorrelatedOverlap,
|
||||||
|
bool supportsBlendEquationAdvancedNonPreMultipliedSrcColor,
|
||||||
|
bool supportsBlendEquationAdvancedNonPreMultipliedDstColor,
|
||||||
bool supportsIndirectParameters,
|
bool supportsIndirectParameters,
|
||||||
bool supportsFragmentShaderInterlock,
|
bool supportsFragmentShaderInterlock,
|
||||||
bool supportsGeometryShaderPassthrough,
|
bool supportsGeometryShaderPassthrough,
|
||||||
|
@ -69,6 +77,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
SupportsIndexTypeUint8 = supportsIndexTypeUint8;
|
||||||
SupportsCustomBorderColor = supportsCustomBorderColor;
|
SupportsCustomBorderColor = supportsCustomBorderColor;
|
||||||
|
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
||||||
|
SupportsBlendEquationAdvancedCorrelatedOverlap = supportsBlendEquationAdvancedCorrelatedOverlap;
|
||||||
|
SupportsBlendEquationAdvancedNonPreMultipliedSrcColor = supportsBlendEquationAdvancedNonPreMultipliedSrcColor;
|
||||||
|
SupportsBlendEquationAdvancedNonPreMultipliedDstColor = supportsBlendEquationAdvancedNonPreMultipliedDstColor;
|
||||||
SupportsIndirectParameters = supportsIndirectParameters;
|
SupportsIndirectParameters = supportsIndirectParameters;
|
||||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||||
|
|
|
@ -112,11 +112,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
||||||
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
new Span<Vector4<float>>(_renderScale).Fill(defaultScale);
|
||||||
|
|
||||||
_newState.Initialize();
|
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
|
||||||
_newState.LineWidth = 1f;
|
|
||||||
_newState.SamplesCount = 1;
|
|
||||||
|
|
||||||
_storedBlend = new PipelineColorBlendAttachmentState[8];
|
_newState.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
|
@ -676,6 +674,49 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// to avoid creating one version of the shader per reference value used.
|
// to avoid creating one version of the shader per reference value used.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetBlendState(AdvancedBlendDescriptor blend)
|
||||||
|
{
|
||||||
|
for (int index = 0; index < Constants.MaxRenderTargets; index++)
|
||||||
|
{
|
||||||
|
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
var blendOp = blend.Op.Convert();
|
||||||
|
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState(
|
||||||
|
blendEnable: true,
|
||||||
|
colorBlendOp: blendOp,
|
||||||
|
alphaBlendOp: blendOp,
|
||||||
|
colorWriteMask: vkBlend.ColorWriteMask);
|
||||||
|
|
||||||
|
if (Gd.Capabilities.SupportsBlendEquationAdvancedNonPreMultipliedSrcColor)
|
||||||
|
{
|
||||||
|
_newState.AdvancedBlendSrcPreMultiplied = blend.SrcPreMultiplied;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Gd.Capabilities.SupportsBlendEquationAdvancedCorrelatedOverlap)
|
||||||
|
{
|
||||||
|
_newState.AdvancedBlendOverlap = blend.Overlap.Convert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState(
|
||||||
|
colorWriteMask: vkBlend.ColorWriteMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vkBlend.ColorWriteMask == 0)
|
||||||
|
{
|
||||||
|
_storedBlend[index] = vkBlend;
|
||||||
|
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SignalStateChange();
|
||||||
|
}
|
||||||
|
|
||||||
public void SetBlendState(int index, BlendDescriptor blend)
|
public void SetBlendState(int index, BlendDescriptor blend)
|
||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||||
|
@ -709,6 +750,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
blend.BlendConstant.Blue,
|
blend.BlendConstant.Blue,
|
||||||
blend.BlendConstant.Alpha);
|
blend.BlendConstant.Alpha);
|
||||||
|
|
||||||
|
// Reset advanced blend state back defaults to the cache to help the pipeline cache.
|
||||||
|
_newState.AdvancedBlendSrcPreMultiplied = true;
|
||||||
|
_newState.AdvancedBlendDstPreMultiplied = true;
|
||||||
|
_newState.AdvancedBlendOverlap = BlendOverlapEXT.UncorrelatedExt;
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AdvancedBlendSrcPreMultiplied
|
||||||
|
{
|
||||||
|
get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
|
||||||
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFB) | ((value ? 1UL : 0UL) << 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AdvancedBlendDstPreMultiplied
|
||||||
|
{
|
||||||
|
get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
|
||||||
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFF7) | ((value ? 1UL : 0UL) << 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlendOverlapEXT AdvancedBlendOverlap
|
||||||
|
{
|
||||||
|
get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
|
||||||
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
|
||||||
|
}
|
||||||
|
|
||||||
public NativeArray<PipelineShaderStageCreateInfo> Stages;
|
public NativeArray<PipelineShaderStageCreateInfo> Stages;
|
||||||
public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
|
public NativeArray<PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT> StageRequiredSubgroupSizes;
|
||||||
public PipelineLayout PipelineLayout;
|
public PipelineLayout PipelineLayout;
|
||||||
|
@ -303,6 +321,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
RequiredSubgroupSize = RequiredSubgroupSize
|
RequiredSubgroupSize = RequiredSubgroupSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AdvancedBlendSrcPreMultiplied = true;
|
||||||
|
AdvancedBlendDstPreMultiplied = true;
|
||||||
|
AdvancedBlendOverlap = BlendOverlapEXT.UncorrelatedExt;
|
||||||
|
|
||||||
|
LineWidth = 1f;
|
||||||
|
SamplesCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe Auto<DisposablePipeline> CreateComputePipeline(
|
public unsafe Auto<DisposablePipeline> CreateComputePipeline(
|
||||||
|
@ -486,6 +511,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PAttachments = pColorBlendAttachmentState
|
PAttachments = pColorBlendAttachmentState
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||||
|
|
||||||
|
if (!AdvancedBlendSrcPreMultiplied ||
|
||||||
|
!AdvancedBlendDstPreMultiplied ||
|
||||||
|
AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
|
||||||
|
{
|
||||||
|
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
|
||||||
|
SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
|
||||||
|
DstPremultiplied = AdvancedBlendDstPreMultiplied,
|
||||||
|
BlendOverlap = AdvancedBlendOverlap
|
||||||
|
};
|
||||||
|
|
||||||
|
colorBlendState.PNext = &colorBlendAdvancedState;
|
||||||
|
}
|
||||||
|
|
||||||
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
||||||
int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
|
int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ExtTransformFeedback.ExtensionName,
|
ExtTransformFeedback.ExtensionName,
|
||||||
KhrDrawIndirectCount.ExtensionName,
|
KhrDrawIndirectCount.ExtensionName,
|
||||||
KhrPushDescriptor.ExtensionName,
|
KhrPushDescriptor.ExtensionName,
|
||||||
|
"VK_EXT_blend_operation_advanced",
|
||||||
"VK_EXT_custom_border_color",
|
"VK_EXT_custom_border_color",
|
||||||
"VK_EXT_descriptor_indexing", // Enabling this works around an issue with disposed buffer bindings on RADV.
|
"VK_EXT_descriptor_indexing", // Enabling this works around an issue with disposed buffer bindings on RADV.
|
||||||
"VK_EXT_fragment_shader_interlock",
|
"VK_EXT_fragment_shader_interlock",
|
||||||
|
|
|
@ -149,6 +149,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SType = StructureType.PhysicalDeviceProperties2
|
SType = StructureType.PhysicalDeviceProperties2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PhysicalDeviceBlendOperationAdvancedPropertiesEXT propertiesBlendOperationAdvanced = new PhysicalDeviceBlendOperationAdvancedPropertiesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceBlendOperationAdvancedPropertiesExt
|
||||||
|
};
|
||||||
|
|
||||||
|
bool supportsBlendOperationAdvanced = supportedExtensions.Contains("VK_EXT_blend_operation_advanced");
|
||||||
|
|
||||||
|
if (supportsBlendOperationAdvanced)
|
||||||
|
{
|
||||||
|
propertiesBlendOperationAdvanced.PNext = properties2.PNext;
|
||||||
|
properties2.PNext = &propertiesBlendOperationAdvanced;
|
||||||
|
}
|
||||||
|
|
||||||
PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
|
PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
|
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
|
||||||
|
@ -246,7 +259,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
portabilityFlags |= featuresPortabilitySubset.SamplerMipLodBias ? 0 : PortabilitySubsetFlags.NoLodBias;
|
portabilityFlags |= featuresPortabilitySubset.SamplerMipLodBias ? 0 : PortabilitySubsetFlags.NoLodBias;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool customBorderColorSupported = supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
bool supportsCustomBorderColor = supportedExtensions.Contains("VK_EXT_custom_border_color") &&
|
||||||
featuresCustomBorderColor.CustomBorderColors &&
|
featuresCustomBorderColor.CustomBorderColors &&
|
||||||
featuresCustomBorderColor.CustomBorderColorWithoutFormat;
|
featuresCustomBorderColor.CustomBorderColorWithoutFormat;
|
||||||
|
|
||||||
|
@ -259,7 +272,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
Capabilities = new HardwareCapabilities(
|
Capabilities = new HardwareCapabilities(
|
||||||
supportedExtensions.Contains("VK_EXT_index_type_uint8"),
|
supportedExtensions.Contains("VK_EXT_index_type_uint8"),
|
||||||
customBorderColorSupported,
|
supportsCustomBorderColor,
|
||||||
|
supportsBlendOperationAdvanced,
|
||||||
|
propertiesBlendOperationAdvanced.AdvancedBlendCorrelatedOverlap,
|
||||||
|
propertiesBlendOperationAdvanced.AdvancedBlendNonPremultipliedSrcColor,
|
||||||
|
propertiesBlendOperationAdvanced.AdvancedBlendNonPremultipliedDstColor,
|
||||||
supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName),
|
supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName),
|
||||||
supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
|
supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
|
||||||
supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
|
supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
|
||||||
|
@ -526,6 +543,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportsR4G4B4A4Format: supportsR4G4B4A4Format,
|
supportsR4G4B4A4Format: supportsR4G4B4A4Format,
|
||||||
supportsSnormBufferTextureFormat: true,
|
supportsSnormBufferTextureFormat: true,
|
||||||
supports5BitComponentFormat: supports5BitComponentFormat,
|
supports5BitComponentFormat: supports5BitComponentFormat,
|
||||||
|
supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
|
||||||
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
||||||
supportsFragmentShaderOrderingIntel: false,
|
supportsFragmentShaderOrderingIntel: false,
|
||||||
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
||||||
|
|
Loading…
Reference in a new issue