diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader')
6 files changed, 59 insertions, 36 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs index 511f4c23..e5e48626 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs @@ -15,62 +15,62 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Early Z force enable. /// </summary> - public readonly bool EarlyZForce; + public bool EarlyZForce; /// <summary> /// Primitive topology of current draw. /// </summary> - public readonly PrimitiveTopology Topology; + public PrimitiveTopology Topology; /// <summary> /// Tessellation mode. /// </summary> - public readonly TessMode TessellationMode; + public TessMode TessellationMode; /// <summary> /// Indicates whether alpha-to-coverage is enabled. /// </summary> - public readonly bool AlphaToCoverageEnable; + public bool AlphaToCoverageEnable; /// <summary> /// Indicates whether alpha-to-coverage dithering is enabled. /// </summary> - public readonly bool AlphaToCoverageDitherEnable; + public bool AlphaToCoverageDitherEnable; /// <summary> /// Indicates whether the viewport transform is disabled. /// </summary> - public readonly bool ViewportTransformDisable; + public bool ViewportTransformDisable; /// <summary> /// Depth mode zero to one or minus one to one. /// </summary> - public readonly bool DepthMode; + public bool DepthMode; /// <summary> /// Indicates if the point size is set on the shader or is fixed. /// </summary> - public readonly bool ProgramPointSizeEnable; + public bool ProgramPointSizeEnable; /// <summary> /// Point size used if <see cref="ProgramPointSizeEnable" /> is false. /// </summary> - public readonly float PointSize; + public float PointSize; /// <summary> /// Indicates whether alpha test is enabled. /// </summary> - public readonly bool AlphaTestEnable; + public bool AlphaTestEnable; /// <summary> /// When alpha test is enabled, indicates the comparison that decides if the fragment should be discarded. /// </summary> - public readonly CompareOp AlphaTestCompare; + public CompareOp AlphaTestCompare; /// <summary> /// When alpha test is enabled, indicates the value to compare with the fragment output alpha. /// </summary> - public readonly float AlphaTestReference; + public float AlphaTestReference; /// <summary> /// Type of the vertex attributes consumed by the shader. @@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0. /// </summary> - public readonly bool HasConstantBufferDrawParameters; + public bool HasConstantBufferDrawParameters; /// <summary> /// Indicates that any storage buffer use is unaligned. /// </summary> - public readonly bool HasUnalignedStorageBuffer; + public bool HasUnalignedStorageBuffer; /// <summary> /// Creates a new GPU graphics state. diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuChannelPoolState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuChannelPoolState.cs index 0b36227a..b894c57e 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuChannelPoolState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuChannelPoolState.cs @@ -1,9 +1,11 @@ +using System; + namespace Ryujinx.Graphics.Gpu.Shader { /// <summary> /// State used by the <see cref="GpuAccessor"/>. /// </summary> - struct GpuChannelPoolState + struct GpuChannelPoolState : IEquatable<GpuChannelPoolState> { /// <summary> /// GPU virtual address of the texture pool. @@ -32,5 +34,17 @@ namespace Ryujinx.Graphics.Gpu.Shader TexturePoolMaximumId = texturePoolMaximumId; TextureBufferIndex = textureBufferIndex; } + + /// <summary> + /// Check if the pool states are equal. + /// </summary> + /// <param name="other">Pool state to compare with</param> + /// <returns>True if they are equal, false otherwise</returns> + public bool Equals(GpuChannelPoolState other) + { + return TexturePoolGpuVa == other.TexturePoolGpuVa && + TexturePoolMaximumId == other.TexturePoolMaximumId && + TextureBufferIndex == other.TextureBufferIndex; + } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 3eaab79f..23b213b4 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -300,16 +300,16 @@ namespace Ryujinx.Graphics.Gpu.Shader ref ThreedClassState state, ref ProgramPipelineState pipeline, GpuChannel channel, - GpuChannelPoolState poolState, - GpuChannelGraphicsState graphicsState, + ref GpuChannelPoolState poolState, + ref GpuChannelGraphicsState graphicsState, ShaderAddresses addresses) { - if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, poolState, graphicsState, gpShaders, addresses)) + if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, ref poolState, ref graphicsState, gpShaders, addresses)) { return gpShaders; } - if (_graphicsShaderCache.TryFind(channel, poolState, graphicsState, addresses, out gpShaders, out var cachedGuestCode)) + if (_graphicsShaderCache.TryFind(channel, ref poolState, ref graphicsState, addresses, out gpShaders, out var cachedGuestCode)) { _gpPrograms[addresses] = gpShaders; return gpShaders; @@ -498,7 +498,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { if (IsShaderEqual(channel.MemoryManager, cpShader.Shaders[0], gpuVa)) { - return cpShader.SpecializationState.MatchesCompute(channel, poolState, computeState, true); + return cpShader.SpecializationState.MatchesCompute(channel, ref poolState, computeState, true); } return false; @@ -515,8 +515,8 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <returns>True if the code is different, false otherwise</returns> private static bool IsShaderEqual( GpuChannel channel, - GpuChannelPoolState poolState, - GpuChannelGraphicsState graphicsState, + ref GpuChannelPoolState poolState, + ref GpuChannelGraphicsState graphicsState, CachedShaderProgram gpShaders, ShaderAddresses addresses) { @@ -536,7 +536,7 @@ namespace Ryujinx.Graphics.Gpu.Shader bool usesDrawParameters = gpShaders.Shaders[1]?.Info.UsesDrawParameters ?? false; - return gpShaders.SpecializationState.MatchesGraphics(channel, poolState, graphicsState, usesDrawParameters, true); + return gpShaders.SpecializationState.MatchesGraphics(channel, ref poolState, ref graphicsState, usesDrawParameters, true); } /// <summary> diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs index 3d74e53a..e35c06b1 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs @@ -215,8 +215,8 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <returns>True if a cached host program was found, false otherwise</returns> public bool TryFind( GpuChannel channel, - GpuChannelPoolState poolState, - GpuChannelGraphicsState graphicsState, + ref GpuChannelPoolState poolState, + ref GpuChannelGraphicsState graphicsState, ShaderAddresses addresses, out CachedShaderProgram program, out CachedGraphicsGuestCode guestCode) @@ -236,7 +236,7 @@ namespace Ryujinx.Graphics.Gpu.Shader if (found && _shaderPrograms.TryGetValue(idTable, out ShaderSpecializationList specList)) { - return specList.TryFindForGraphics(channel, poolState, graphicsState, out program); + return specList.TryFindForGraphics(channel, ref poolState, ref graphicsState, out program); } return false; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs index cb6ab49a..7d61332e 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs @@ -29,15 +29,15 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <returns>True if a compatible program is found, false otherwise</returns> public bool TryFindForGraphics( GpuChannel channel, - GpuChannelPoolState poolState, - GpuChannelGraphicsState graphicsState, + ref GpuChannelPoolState poolState, + ref GpuChannelGraphicsState graphicsState, out CachedShaderProgram program) { foreach (var entry in _entries) { bool usesDrawParameters = entry.Shaders[1]?.Info.UsesDrawParameters ?? false; - if (entry.SpecializationState.MatchesGraphics(channel, poolState, graphicsState, usesDrawParameters, true)) + if (entry.SpecializationState.MatchesGraphics(channel, ref poolState, ref graphicsState, usesDrawParameters, true)) { program = entry; return true; @@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { foreach (var entry in _entries) { - if (entry.SpecializationState.MatchesCompute(channel, poolState, computeState, true)) + if (entry.SpecializationState.MatchesCompute(channel, ref poolState, computeState, true)) { program = entry; return true; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index 8f931507..14f64bbf 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -393,6 +393,15 @@ namespace Ryujinx.Graphics.Gpu.Shader } /// <summary> + /// Checks if primitive topology was queried by the shader. + /// </summary> + /// <returns>True if queried, false otherwise</returns> + public bool IsPrimitiveTopologyQueried() + { + return _queriedState.HasFlag(QueriedStateFlags.PrimitiveTopology); + } + + /// <summary> /// Checks if a given texture was registerd on this specialization state. /// </summary> /// <param name="stageIndex">Shader stage where the texture is used</param> @@ -486,8 +495,8 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <returns>True if the state matches, false otherwise</returns> public bool MatchesGraphics( GpuChannel channel, - GpuChannelPoolState poolState, - GpuChannelGraphicsState graphicsState, + ref GpuChannelPoolState poolState, + ref GpuChannelGraphicsState graphicsState, bool usesDrawParameters, bool checkTextures) { @@ -536,7 +545,7 @@ namespace Ryujinx.Graphics.Gpu.Shader return false; } - return Matches(channel, poolState, checkTextures, isCompute: false); + return Matches(channel, ref poolState, checkTextures, isCompute: false); } /// <summary> @@ -547,14 +556,14 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="computeState">Compute state</param> /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param> /// <returns>True if the state matches, false otherwise</returns> - public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, bool checkTextures) + public bool MatchesCompute(GpuChannel channel, ref GpuChannelPoolState poolState, GpuChannelComputeState computeState, bool checkTextures) { if (computeState.HasUnalignedStorageBuffer != ComputeState.HasUnalignedStorageBuffer) { return false; } - return Matches(channel, poolState, checkTextures, isCompute: true); + return Matches(channel, ref poolState, checkTextures, isCompute: true); } /// <summary> @@ -618,7 +627,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param> /// <param name="isCompute">Indicates whenever the check is requested by the 3D or compute engine</param> /// <returns>True if the state matches, false otherwise</returns> - private bool Matches(GpuChannel channel, GpuChannelPoolState poolState, bool checkTextures, bool isCompute) + private bool Matches(GpuChannel channel, ref GpuChannelPoolState poolState, bool checkTextures, bool isCompute) { int constantBufferUsePerStageMask = _constantBufferUsePerStage; |
