aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.GAL/BlendDescriptor.cs3
-rw-r--r--Ryujinx.Graphics.GAL/ColorF.cs16
-rw-r--r--Ryujinx.Graphics.GAL/IPipeline.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs6
-rw-r--r--Ryujinx.Graphics.Gpu/State/BlendState.cs10
-rw-r--r--Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs10
-rw-r--r--Ryujinx.Graphics.Gpu/State/GpuState.cs80
-rw-r--r--Ryujinx.Graphics.Gpu/State/GpuStateTable.cs10
-rw-r--r--Ryujinx.Graphics.Gpu/State/MethodOffset.cs1
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs18
10 files changed, 140 insertions, 16 deletions
diff --git a/Ryujinx.Graphics.GAL/BlendDescriptor.cs b/Ryujinx.Graphics.GAL/BlendDescriptor.cs
index b35a0169..cc1e17c7 100644
--- a/Ryujinx.Graphics.GAL/BlendDescriptor.cs
+++ b/Ryujinx.Graphics.GAL/BlendDescriptor.cs
@@ -4,6 +4,7 @@ namespace Ryujinx.Graphics.GAL
{
public bool Enable { get; }
+ public ColorF BlendConstant { get; }
public BlendOp ColorOp { get; }
public BlendFactor ColorSrcFactor { get; }
public BlendFactor ColorDstFactor { get; }
@@ -13,6 +14,7 @@ namespace Ryujinx.Graphics.GAL
public BlendDescriptor(
bool enable,
+ ColorF blendConstant,
BlendOp colorOp,
BlendFactor colorSrcFactor,
BlendFactor colorDstFactor,
@@ -21,6 +23,7 @@ namespace Ryujinx.Graphics.GAL
BlendFactor alphaDstFactor)
{
Enable = enable;
+ BlendConstant = blendConstant;
ColorOp = colorOp;
ColorSrcFactor = colorSrcFactor;
ColorDstFactor = colorDstFactor;
diff --git a/Ryujinx.Graphics.GAL/ColorF.cs b/Ryujinx.Graphics.GAL/ColorF.cs
index 2e971a62..b3002f8c 100644
--- a/Ryujinx.Graphics.GAL/ColorF.cs
+++ b/Ryujinx.Graphics.GAL/ColorF.cs
@@ -1,6 +1,8 @@
+using System;
+
namespace Ryujinx.Graphics.GAL
{
- public struct ColorF
+ public struct ColorF : IEquatable<ColorF>
{
public float Red { get; }
public float Green { get; }
@@ -14,5 +16,17 @@ namespace Ryujinx.Graphics.GAL
Blue = blue;
Alpha = alpha;
}
+
+ public bool Equals(ColorF color) => Red == color.Red &&
+ Green == color.Green &&
+ Blue == color.Blue &&
+ Alpha == color.Alpha;
+
+ public override bool Equals(object obj) => (obj is ColorF color) && Equals(color);
+
+ public override int GetHashCode() => HashCode.Combine(Red, Green, Blue, Alpha);
+
+ public static bool operator ==(ColorF l, ColorF r) => l.Equals(r);
+ public static bool operator !=(ColorF l, ColorF r) => !l.Equals(r);
}
}
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 4c892bea..1e685923 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -26,8 +26,6 @@ namespace Ryujinx.Graphics.GAL
void SetBlendState(int index, BlendDescriptor blend);
- void SetBlendColor(ColorF color);
-
void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);
void SetDepthClamp(bool clampNear, bool clampFar);
void SetDepthMode(DepthMode mode);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index 2e6c9828..7bc85018 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -229,6 +229,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
}
if (state.QueryModified(MethodOffset.BlendIndependent,
+ MethodOffset.BlendConstant,
MethodOffset.BlendStateCommon,
MethodOffset.BlendEnableCommon,
MethodOffset.BlendEnable,
@@ -749,8 +750,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
private void UpdateBlendState(GpuState state)
{
bool blendIndependent = state.Get<Boolean32>(MethodOffset.BlendIndependent);
+ ColorF blendConstant = state.Get<ColorF>(MethodOffset.BlendConstant);
- for (int index = 0; index < 8; index++)
+ for (int index = 0; index < Constants.TotalRenderTargets; index++)
{
BlendDescriptor descriptor;
@@ -761,6 +763,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
descriptor = new BlendDescriptor(
enable,
+ blendConstant,
blend.ColorOp,
blend.ColorSrcFactor,
blend.ColorDstFactor,
@@ -775,6 +778,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
descriptor = new BlendDescriptor(
enable,
+ blendConstant,
blend.ColorOp,
blend.ColorSrcFactor,
blend.ColorDstFactor,
diff --git a/Ryujinx.Graphics.Gpu/State/BlendState.cs b/Ryujinx.Graphics.Gpu/State/BlendState.cs
index c4d5a064..ba16b8bd 100644
--- a/Ryujinx.Graphics.Gpu/State/BlendState.cs
+++ b/Ryujinx.Graphics.Gpu/State/BlendState.cs
@@ -17,5 +17,15 @@ namespace Ryujinx.Graphics.Gpu.State
public BlendFactor AlphaDstFactor;
public uint Padding;
#pragma warning restore CS0649
+
+ public static BlendState Default = new BlendState
+ {
+ ColorOp = BlendOp.Add,
+ ColorSrcFactor = BlendFactor.One,
+ ColorDstFactor = BlendFactor.Zero,
+ AlphaOp = BlendOp.Add,
+ AlphaSrcFactor = BlendFactor.One,
+ AlphaDstFactor = BlendFactor.Zero
+ };
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs b/Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs
index cbb1880b..f402a5a7 100644
--- a/Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs
+++ b/Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs
@@ -17,5 +17,15 @@ namespace Ryujinx.Graphics.Gpu.State
public uint Unknown0x1354;
public BlendFactor AlphaDstFactor;
#pragma warning restore CS0649
+
+ public static BlendStateCommon Default = new BlendStateCommon
+ {
+ ColorOp = BlendOp.Add,
+ ColorSrcFactor = BlendFactor.One,
+ ColorDstFactor = BlendFactor.Zero,
+ AlphaOp = BlendOp.Add,
+ AlphaSrcFactor = BlendFactor.One,
+ AlphaDstFactor = BlendFactor.Zero
+ };
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/GpuState.cs b/Ryujinx.Graphics.Gpu/State/GpuState.cs
index 981b96b7..a6671fe8 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuState.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuState.cs
@@ -141,6 +141,14 @@ namespace Ryujinx.Graphics.Gpu.State
{
_backingMemory[(int)MethodOffset.RtColorMask + index] = 0x1111;
}
+
+ // Default blend states
+ Set(MethodOffset.BlendStateCommon, BlendStateCommon.Default);
+
+ for (int index = 0; index < Constants.TotalRenderTargets; index++)
+ {
+ Set(MethodOffset.BlendState, index, BlendState.Default);
+ }
}
/// <summary>
@@ -199,7 +207,7 @@ namespace Ryujinx.Graphics.Gpu.State
}
/// <summary>
- /// Checks if two registers have been modified since the last call to this method.
+ /// Checks if three registers have been modified since the last call to this method.
/// </summary>
/// <param name="m1">First register offset</param>
/// <param name="m2">Second register offset</param>
@@ -219,7 +227,7 @@ namespace Ryujinx.Graphics.Gpu.State
}
/// <summary>
- /// Checks if two registers have been modified since the last call to this method.
+ /// Checks if four registers have been modified since the last call to this method.
/// </summary>
/// <param name="m1">First register offset</param>
/// <param name="m2">Second register offset</param>
@@ -242,7 +250,7 @@ namespace Ryujinx.Graphics.Gpu.State
}
/// <summary>
- /// Checks if two registers have been modified since the last call to this method.
+ /// Checks if five registers have been modified since the last call to this method.
/// </summary>
/// <param name="m1">First register offset</param>
/// <param name="m2">Second register offset</param>
@@ -273,6 +281,41 @@ namespace Ryujinx.Graphics.Gpu.State
}
/// <summary>
+ /// Checks if six registers have been modified since the last call to this method.
+ /// </summary>
+ /// <param name="m1">First register offset</param>
+ /// <param name="m2">Second register offset</param>
+ /// <param name="m3">Third register offset</param>
+ /// <param name="m4">Fourth register offset</param>
+ /// <param name="m5">Fifth register offset</param>
+ /// <param name="m6">Sixth register offset</param>
+ /// <returns>True if any register was modified, false otherwise</returns>
+ public bool QueryModified(
+ MethodOffset m1,
+ MethodOffset m2,
+ MethodOffset m3,
+ MethodOffset m4,
+ MethodOffset m5,
+ MethodOffset m6)
+ {
+ bool modified = _registers[(int)m1].Modified ||
+ _registers[(int)m2].Modified ||
+ _registers[(int)m3].Modified ||
+ _registers[(int)m4].Modified ||
+ _registers[(int)m5].Modified ||
+ _registers[(int)m6].Modified;
+
+ _registers[(int)m1].Modified = false;
+ _registers[(int)m2].Modified = false;
+ _registers[(int)m3].Modified = false;
+ _registers[(int)m4].Modified = false;
+ _registers[(int)m5].Modified = false;
+ _registers[(int)m6].Modified = false;
+
+ return modified;
+ }
+
+ /// <summary>
/// Gets indexed data from a given register offset.
/// </summary>
/// <typeparam name="T">Type of the data</typeparam>
@@ -301,5 +344,36 @@ namespace Ryujinx.Graphics.Gpu.State
{
return MemoryMarshal.Cast<int, T>(_backingMemory.AsSpan().Slice((int)offset))[0];
}
+
+ /// <summary>
+ /// Sets indexed data to a given register offset.
+ /// </summary>
+ /// <typeparam name="T">Type of the data</typeparam>
+ /// <param name="offset">Register offset</param>
+ /// <param name="index">Index for indexed data</param>
+ /// <param name="data">The data to set</param>
+ public void Set<T>(MethodOffset offset, int index, T data) where T : struct
+ {
+ Register register = _registers[(int)offset];
+
+ if ((uint)index >= register.Count)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+
+ Set(offset + index * register.Stride, data);
+ }
+
+ /// <summary>
+ /// Sets data to a given register offset.
+ /// </summary>
+ /// <typeparam name="T">Type of the data</typeparam>
+ /// <param name="offset">Register offset</param>
+ /// <param name="data">The data to set</param>
+ public void Set<T>(MethodOffset offset, T data) where T : struct
+ {
+ ReadOnlySpan<int> intSpan = MemoryMarshal.Cast<T, int>(MemoryMarshal.CreateReadOnlySpan(ref data, 1));
+ intSpan.CopyTo(_backingMemory.AsSpan().Slice((int)offset, intSpan.Length));
+ }
}
}
diff --git a/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs b/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
index e59a3aaf..65df5f4e 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuStateTable.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Graphics.GAL;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
@@ -52,7 +53,7 @@ namespace Ryujinx.Graphics.Gpu.State
/// </summary>
public static TableItem[] Table = new TableItem[]
{
- new TableItem(MethodOffset.RtColorState, typeof(RtColorState), 8),
+ new TableItem(MethodOffset.RtColorState, typeof(RtColorState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), Constants.TotalViewports),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), Constants.TotalViewports),
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1),
@@ -62,7 +63,7 @@ namespace Ryujinx.Graphics.Gpu.State
new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1),
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16),
new TableItem(MethodOffset.RtDepthStencilSize, typeof(Size3D), 1),
- new TableItem(MethodOffset.BlendEnable, typeof(Boolean32), 8),
+ new TableItem(MethodOffset.BlendEnable, typeof(Boolean32), Constants.TotalRenderTargets),
new TableItem(MethodOffset.StencilTestState, typeof(StencilTestState), 1),
new TableItem(MethodOffset.SamplerPoolState, typeof(PoolState), 1),
new TableItem(MethodOffset.TexturePoolState, typeof(PoolState), 1),
@@ -72,9 +73,10 @@ namespace Ryujinx.Graphics.Gpu.State
new TableItem(MethodOffset.IndexBufferState, typeof(IndexBufferState), 1),
new TableItem(MethodOffset.VertexBufferInstanced, typeof(Boolean32), 16),
new TableItem(MethodOffset.FaceState, typeof(FaceState), 1),
- new TableItem(MethodOffset.RtColorMask, typeof(RtColorMask), 8),
+ new TableItem(MethodOffset.RtColorMask, typeof(RtColorMask), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferState, typeof(VertexBufferState), 16),
- new TableItem(MethodOffset.BlendState, typeof(BlendState), 8),
+ new TableItem(MethodOffset.BlendConstant, typeof(ColorF), 1),
+ new TableItem(MethodOffset.BlendState, typeof(BlendState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferEndAddress, typeof(GpuVa), 16),
new TableItem(MethodOffset.ShaderState, typeof(ShaderState), 6),
};
diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
index b542d9b8..077b09c2 100644
--- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
+++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
@@ -58,6 +58,7 @@ namespace Ryujinx.Graphics.Gpu.State
BlendIndependent = 0x4b9,
DepthWriteEnable = 0x4ba,
DepthTestFunc = 0x4c3,
+ BlendConstant = 0x4c7,
BlendStateCommon = 0x4cf,
BlendEnableCommon = 0x4d7,
BlendEnable = 0x4d8,
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index e32b5b85..eec2b643 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -35,6 +35,8 @@ namespace Ryujinx.Graphics.OpenGL
private bool _scissor0Enable = false;
+ ColorF _blendConstant = new ColorF(0, 0, 0, 0);
+
internal Pipeline()
{
_rasterizerDiscard = false;
@@ -478,11 +480,6 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- public void SetBlendColor(ColorF color)
- {
- GL.BlendColor(color.Red, color.Green, color.Blue, color.Alpha);
- }
-
public void SetBlendState(int index, BlendDescriptor blend)
{
if (!blend.Enable)
@@ -504,6 +501,17 @@ namespace Ryujinx.Graphics.OpenGL
(BlendingFactorSrc)blend.AlphaSrcFactor.Convert(),
(BlendingFactorDest)blend.AlphaDstFactor.Convert());
+ if (_blendConstant != blend.BlendConstant)
+ {
+ _blendConstant = blend.BlendConstant;
+
+ GL.BlendColor(
+ blend.BlendConstant.Red,
+ blend.BlendConstant.Green,
+ blend.BlendConstant.Blue,
+ blend.BlendConstant.Alpha);
+ }
+
GL.Enable(IndexedEnableCap.Blend, index);
}