diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index 7e39c8a3..c927f33d 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -1,6 +1,7 @@ using Ryujinx.Common.Memory; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Shader.DiskCache; using Ryujinx.Graphics.Shader; using System; @@ -19,6 +20,7 @@ namespace Ryujinx.Graphics.Gpu.Shader private const uint TfbdMagic = (byte)'T' | ((byte)'F' << 8) | ((byte)'B' << 16) | ((byte)'D' << 24); private const uint TexkMagic = (byte)'T' | ((byte)'E' << 8) | ((byte)'X' << 16) | ((byte)'K' << 24); private const uint TexsMagic = (byte)'T' | ((byte)'E' << 8) | ((byte)'X' << 16) | ((byte)'S' << 24); + private const uint PgpsMagic = (byte)'P' | ((byte)'G' << 8) | ((byte)'P' << 16) | ((byte)'S' << 24); /// <summary> /// Flags indicating GPU state that is used by the shader. @@ -52,6 +54,11 @@ namespace Ryujinx.Graphics.Gpu.Shader public Array5<uint> ConstantBufferUse; /// <summary> + /// Pipeline state captured at the time of shader use. + /// </summary> + public ProgramPipelineState? PipelineState; + + /// <summary> /// Transform feedback buffers active at the time the shader was compiled. /// </summary> public TransformFeedbackDescriptor[] TransformFeedbackDescriptors; @@ -179,7 +186,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Creates a new instance of the shader specialization state. /// </summary> /// <param name="state">Current compute engine state</param> - public ShaderSpecializationState(GpuChannelComputeState state) : this() + public ShaderSpecializationState(ref GpuChannelComputeState state) : this() { ComputeState = state; _compute = true; @@ -190,7 +197,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="state">Current 3D engine state</param> /// <param name="descriptors">Optional transform feedback buffers in use, if any</param> - public ShaderSpecializationState(GpuChannelGraphicsState state, TransformFeedbackDescriptor[] descriptors) : this() + private ShaderSpecializationState(ref GpuChannelGraphicsState state, TransformFeedbackDescriptor[] descriptors) : this() { GraphicsState = state; _compute = false; @@ -245,6 +252,34 @@ namespace Ryujinx.Graphics.Gpu.Shader } /// <summary> + /// Creates a new instance of the shader specialization state. + /// </summary> + /// <param name="state">Current 3D engine state</param> + /// <param name="pipelineState">Current program pipeline state</param> + /// <param name="descriptors">Optional transform feedback buffers in use, if any</param> + public ShaderSpecializationState( + ref GpuChannelGraphicsState state, + ref ProgramPipelineState pipelineState, + TransformFeedbackDescriptor[] descriptors) : this(ref state, descriptors) + { + PipelineState = pipelineState; + } + + /// <summary> + /// Creates a new instance of the shader specialization state. + /// </summary> + /// <param name="state">Current 3D engine state</param> + /// <param name="pipelineState">Current program pipeline state</param> + /// <param name="descriptors">Optional transform feedback buffers in use, if any</param> + public ShaderSpecializationState( + ref GpuChannelGraphicsState state, + ProgramPipelineState? pipelineState, + TransformFeedbackDescriptor[] descriptors) : this(ref state, descriptors) + { + PipelineState = pipelineState; + } + + /// <summary> /// Indicates that the shader accesses the early Z force state. /// </summary> public void RecordEarlyZForce() @@ -463,6 +498,28 @@ namespace Ryujinx.Graphics.Gpu.Shader return false; } + if (graphicsState.DepthMode != GraphicsState.DepthMode) + { + return false; + } + + if (graphicsState.AlphaTestEnable != GraphicsState.AlphaTestEnable) + { + return false; + } + + if (graphicsState.AlphaTestEnable && + (graphicsState.AlphaTestCompare != GraphicsState.AlphaTestCompare || + graphicsState.AlphaTestReference != GraphicsState.AlphaTestReference)) + { + return false; + } + + if (!graphicsState.AttributeTypes.ToSpan().SequenceEqual(GraphicsState.AttributeTypes.ToSpan())) + { + return false; + } + return Matches(channel, poolState, checkTextures, isCompute: false); } @@ -685,6 +742,17 @@ namespace Ryujinx.Graphics.Gpu.Shader constantBufferUsePerStageMask &= ~(1 << index); } + bool hasPipelineState = false; + + dataReader.Read(ref hasPipelineState); + + if (hasPipelineState) + { + ProgramPipelineState pipelineState = default; + dataReader.ReadWithMagicAndSize(ref pipelineState, PgpsMagic); + specState.PipelineState = pipelineState; + } + if (specState._queriedState.HasFlag(QueriedStateFlags.TransformFeedback)) { ushort tfCount = 0; @@ -743,6 +811,16 @@ namespace Ryujinx.Graphics.Gpu.Shader constantBufferUsePerStageMask &= ~(1 << index); } + bool hasPipelineState = PipelineState.HasValue; + + dataWriter.Write(ref hasPipelineState); + + if (hasPipelineState) + { + ProgramPipelineState pipelineState = PipelineState.Value; + dataWriter.WriteWithMagicAndSize(ref pipelineState, PgpsMagic); + } + if (_queriedState.HasFlag(QueriedStateFlags.TransformFeedback)) { ushort tfCount = (ushort)TransformFeedbackDescriptors.Length; |