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:
gdkchan
2023-02-19 22:37:37 -03:00
committed by GitHub
parent 6bf460e104
commit 7aa430f1a5
27 changed files with 5605 additions and 14 deletions

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

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

View File

@ -0,0 +1,9 @@
namespace Ryujinx.Graphics.GAL
{
public enum AdvancedBlendOverlap
{
Uncorrelated,
Disjoint,
Conjoint
}
}

View File

@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsR4G4B4A4Format;
public readonly bool SupportsSnormBufferTextureFormat;
public readonly bool Supports5BitComponentFormat;
public readonly bool SupportsBlendEquationAdvanced;
public readonly bool SupportsFragmentShaderInterlock;
public readonly bool SupportsFragmentShaderOrderingIntel;
public readonly bool SupportsGeometryShaderPassthrough;
@ -64,6 +65,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsR4G4B4A4Format,
bool supportsSnormBufferTextureFormat,
bool supports5BitComponentFormat,
bool supportsBlendEquationAdvanced,
bool supportsFragmentShaderInterlock,
bool supportsFragmentShaderOrderingIntel,
bool supportsGeometryShaderPassthrough,
@ -102,6 +104,7 @@ namespace Ryujinx.Graphics.GAL
SupportsR4G4B4A4Format = supportsR4G4B4A4Format;
SupportsSnormBufferTextureFormat = supportsSnormBufferTextureFormat;
Supports5BitComponentFormat = supports5BitComponentFormat;
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;

View File

@ -44,6 +44,7 @@ namespace Ryujinx.Graphics.GAL
void SetAlphaTest(bool enable, float reference, CompareOp op);
void SetBlendState(AdvancedBlendDescriptor blend);
void SetBlendState(int index, BlendDescriptor blend);
void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);

View File

@ -98,6 +98,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
Register<SetBlendStateAdvancedCommand>(CommandType.SetBlendStateAdvanced);
Register<SetBlendStateCommand>(CommandType.SetBlendState);
Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
Register<SetDepthClampCommand>(CommandType.SetDepthClamp);

View File

@ -60,6 +60,7 @@
EndHostConditionalRendering,
EndTransformFeedback,
SetAlphaTest,
SetBlendStateAdvanced,
SetBlendState,
SetDepthBias,
SetDepthClamp,

View File

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

View File

@ -131,6 +131,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_renderer.QueueCommand();
}
public void SetBlendState(AdvancedBlendDescriptor blend)
{
_renderer.New<SetBlendStateAdvancedCommand>().Set(blend);
_renderer.QueueCommand();
}
public void SetBlendState(int index, BlendDescriptor blend)
{
_renderer.New<SetBlendStateCommand>().Set(index, blend);