aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
-rw-r--r--Ryujinx.Graphics.OpenGL/EnumConversion.cs120
-rw-r--r--Ryujinx.Graphics.OpenGL/HwCapabilities.cs2
-rw-r--r--Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs1
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs19
4 files changed, 142 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/EnumConversion.cs b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
index f262c584..c9a1eaa9 100644
--- a/Ryujinx.Graphics.OpenGL/EnumConversion.cs
+++ b/Ryujinx.Graphics.OpenGL/EnumConversion.cs
@@ -34,6 +34,126 @@ namespace Ryujinx.Graphics.OpenGL
return TextureWrapMode.Clamp;
}
+ public static NvBlendEquationAdvanced Convert(this AdvancedBlendOp op)
+ {
+ switch (op)
+ {
+ case AdvancedBlendOp.Zero:
+ return NvBlendEquationAdvanced.Zero;
+ case AdvancedBlendOp.Src:
+ return NvBlendEquationAdvanced.SrcNv;
+ case AdvancedBlendOp.Dst:
+ return NvBlendEquationAdvanced.DstNv;
+ case AdvancedBlendOp.SrcOver:
+ return NvBlendEquationAdvanced.SrcOverNv;
+ case AdvancedBlendOp.DstOver:
+ return NvBlendEquationAdvanced.DstOverNv;
+ case AdvancedBlendOp.SrcIn:
+ return NvBlendEquationAdvanced.SrcInNv;
+ case AdvancedBlendOp.DstIn:
+ return NvBlendEquationAdvanced.DstInNv;
+ case AdvancedBlendOp.SrcOut:
+ return NvBlendEquationAdvanced.SrcOutNv;
+ case AdvancedBlendOp.DstOut:
+ return NvBlendEquationAdvanced.DstOutNv;
+ case AdvancedBlendOp.SrcAtop:
+ return NvBlendEquationAdvanced.SrcAtopNv;
+ case AdvancedBlendOp.DstAtop:
+ return NvBlendEquationAdvanced.DstAtopNv;
+ case AdvancedBlendOp.Xor:
+ return NvBlendEquationAdvanced.XorNv;
+ case AdvancedBlendOp.Plus:
+ return NvBlendEquationAdvanced.PlusNv;
+ case AdvancedBlendOp.PlusClamped:
+ return NvBlendEquationAdvanced.PlusClampedNv;
+ case AdvancedBlendOp.PlusClampedAlpha:
+ return NvBlendEquationAdvanced.PlusClampedAlphaNv;
+ case AdvancedBlendOp.PlusDarker:
+ return NvBlendEquationAdvanced.PlusDarkerNv;
+ case AdvancedBlendOp.Multiply:
+ return NvBlendEquationAdvanced.MultiplyNv;
+ case AdvancedBlendOp.Screen:
+ return NvBlendEquationAdvanced.ScreenNv;
+ case AdvancedBlendOp.Overlay:
+ return NvBlendEquationAdvanced.OverlayNv;
+ case AdvancedBlendOp.Darken:
+ return NvBlendEquationAdvanced.DarkenNv;
+ case AdvancedBlendOp.Lighten:
+ return NvBlendEquationAdvanced.LightenNv;
+ case AdvancedBlendOp.ColorDodge:
+ return NvBlendEquationAdvanced.ColordodgeNv;
+ case AdvancedBlendOp.ColorBurn:
+ return NvBlendEquationAdvanced.ColorburnNv;
+ case AdvancedBlendOp.HardLight:
+ return NvBlendEquationAdvanced.HardlightNv;
+ case AdvancedBlendOp.SoftLight:
+ return NvBlendEquationAdvanced.SoftlightNv;
+ case AdvancedBlendOp.Difference:
+ return NvBlendEquationAdvanced.DifferenceNv;
+ case AdvancedBlendOp.Minus:
+ return NvBlendEquationAdvanced.MinusNv;
+ case AdvancedBlendOp.MinusClamped:
+ return NvBlendEquationAdvanced.MinusClampedNv;
+ case AdvancedBlendOp.Exclusion:
+ return NvBlendEquationAdvanced.ExclusionNv;
+ case AdvancedBlendOp.Contrast:
+ return NvBlendEquationAdvanced.ContrastNv;
+ case AdvancedBlendOp.Invert:
+ return NvBlendEquationAdvanced.Invert;
+ case AdvancedBlendOp.InvertRGB:
+ return NvBlendEquationAdvanced.InvertRgbNv;
+ case AdvancedBlendOp.InvertOvg:
+ return NvBlendEquationAdvanced.InvertOvgNv;
+ case AdvancedBlendOp.LinearDodge:
+ return NvBlendEquationAdvanced.LineardodgeNv;
+ case AdvancedBlendOp.LinearBurn:
+ return NvBlendEquationAdvanced.LinearburnNv;
+ case AdvancedBlendOp.VividLight:
+ return NvBlendEquationAdvanced.VividlightNv;
+ case AdvancedBlendOp.LinearLight:
+ return NvBlendEquationAdvanced.LinearlightNv;
+ case AdvancedBlendOp.PinLight:
+ return NvBlendEquationAdvanced.PinlightNv;
+ case AdvancedBlendOp.HardMix:
+ return NvBlendEquationAdvanced.HardmixNv;
+ case AdvancedBlendOp.Red:
+ return NvBlendEquationAdvanced.RedNv;
+ case AdvancedBlendOp.Green:
+ return NvBlendEquationAdvanced.GreenNv;
+ case AdvancedBlendOp.Blue:
+ return NvBlendEquationAdvanced.BlueNv;
+ case AdvancedBlendOp.HslHue:
+ return NvBlendEquationAdvanced.HslHueNv;
+ case AdvancedBlendOp.HslSaturation:
+ return NvBlendEquationAdvanced.HslSaturationNv;
+ case AdvancedBlendOp.HslColor:
+ return NvBlendEquationAdvanced.HslColorNv;
+ case AdvancedBlendOp.HslLuminosity:
+ return NvBlendEquationAdvanced.HslLuminosityNv;
+ }
+
+ Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOp)} enum value: {op}.");
+
+ return NvBlendEquationAdvanced.Zero;
+ }
+
+ public static All Convert(this AdvancedBlendOverlap overlap)
+ {
+ switch (overlap)
+ {
+ case AdvancedBlendOverlap.Uncorrelated:
+ return All.UncorrelatedNv;
+ case AdvancedBlendOverlap.Disjoint:
+ return All.DisjointNv;
+ case AdvancedBlendOverlap.Conjoint:
+ return All.ConjointNv;
+ }
+
+ Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOverlap)} enum value: {overlap}.");
+
+ return All.UncorrelatedNv;
+ }
+
public static All Convert(this BlendFactor factor)
{
switch (factor)
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index 8caf11dd..84646526 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.OpenGL
{
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
+ private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced"));
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
@@ -51,6 +52,7 @@ namespace Ryujinx.Graphics.OpenGL
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
+ public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
diff --git a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index 30ed942d..722c4b4d 100644
--- a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -119,6 +119,7 @@ namespace Ryujinx.Graphics.OpenGL
supportsR4G4B4A4Format: true,
supportsSnormBufferTextureFormat: false,
supports5BitComponentFormat: true,
+ supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 8bcaf4c7..970feea0 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -59,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
private uint _fragmentOutputMap;
private uint _componentMasks;
private uint _currentComponentMasks;
+ private bool _advancedBlendEnable;
private uint _scissorEnables;
@@ -784,8 +785,26 @@ namespace Ryujinx.Graphics.OpenGL
GL.Enable(EnableCap.AlphaTest);
}
+ public void SetBlendState(AdvancedBlendDescriptor blend)
+ {
+ if (HwCapabilities.SupportsBlendEquationAdvanced)
+ {
+ GL.BlendEquation((BlendEquationMode)blend.Op.Convert());
+ GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendOverlapNv, (int)blend.Overlap.Convert());
+ GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendPremultipliedSrcNv, blend.SrcPreMultiplied ? 1 : 0);
+ GL.Enable(EnableCap.Blend);
+ _advancedBlendEnable = true;
+ }
+ }
+
public void SetBlendState(int index, BlendDescriptor blend)
{
+ if (_advancedBlendEnable)
+ {
+ GL.Disable(EnableCap.Blend);
+ _advancedBlendEnable = false;
+ }
+
if (!blend.Enable)
{
GL.Disable(IndexedEnableCap.Blend, index);