From a728610b4016e153fed670eddaa45909ab51f18b Mon Sep 17 00:00:00 2001 From: mageven <62494521+mageven@users.noreply.github.com> Date: Sat, 25 Apr 2020 18:30:43 +0530 Subject: Implement Constant Color blends (#1119) * Implement Constant Color blends and init blend states * Address gdkchan's comments Also adds Set methods to GpuState * Fix descriptions of QueryModified --- Ryujinx.Graphics.Gpu/State/BlendState.cs | 10 ++++ Ryujinx.Graphics.Gpu/State/BlendStateCommon.cs | 10 ++++ Ryujinx.Graphics.Gpu/State/GpuState.cs | 80 +++++++++++++++++++++++++- Ryujinx.Graphics.Gpu/State/GpuStateTable.cs | 10 ++-- Ryujinx.Graphics.Gpu/State/MethodOffset.cs | 1 + 5 files changed, 104 insertions(+), 7 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/State') 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); + } } /// @@ -199,7 +207,7 @@ namespace Ryujinx.Graphics.Gpu.State } /// - /// 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. /// /// First register offset /// Second register offset @@ -219,7 +227,7 @@ namespace Ryujinx.Graphics.Gpu.State } /// - /// 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. /// /// First register offset /// Second register offset @@ -242,7 +250,7 @@ namespace Ryujinx.Graphics.Gpu.State } /// - /// 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. /// /// First register offset /// Second register offset @@ -272,6 +280,41 @@ namespace Ryujinx.Graphics.Gpu.State return modified; } + /// + /// Checks if six registers have been modified since the last call to this method. + /// + /// First register offset + /// Second register offset + /// Third register offset + /// Fourth register offset + /// Fifth register offset + /// Sixth register offset + /// True if any register was modified, false otherwise + 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; + } + /// /// Gets indexed data from a given register offset. /// @@ -301,5 +344,36 @@ namespace Ryujinx.Graphics.Gpu.State { return MemoryMarshal.Cast(_backingMemory.AsSpan().Slice((int)offset))[0]; } + + /// + /// Sets indexed data to a given register offset. + /// + /// Type of the data + /// Register offset + /// Index for indexed data + /// The data to set + public void Set(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); + } + + /// + /// Sets data to a given register offset. + /// + /// Type of the data + /// Register offset + /// The data to set + public void Set(MethodOffset offset, T data) where T : struct + { + ReadOnlySpan intSpan = MemoryMarshal.Cast(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 /// 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, -- cgit v1.2.3