From 43b4b34376cdea486906f8bb4058dda3be7e1bd8 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Thu, 12 May 2022 14:47:13 +0100 Subject: Implement Viewport Transform Disable (#3328) * Initial implementation (no specialization) * Use specialization * Fix render scale, increase code gen version * Revert accidental change * Address Feedback --- Ryujinx.Graphics.Gpu/Shader/Cache/Migration.cs | 3 ++- Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs | 6 ++++++ Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs | 2 +- Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs | 6 ++++++ Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs | 9 ++++++++- Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 8 +++++--- Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs | 4 +++- Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs | 9 +++++++-- Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs | 8 +++++++- 9 files changed, 45 insertions(+), 10 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/Shader') diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/Migration.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/Migration.cs index 27fac8f3..4de6eff9 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/Migration.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/Migration.cs @@ -166,7 +166,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache GpuChannelGraphicsState graphicsState = new GpuChannelGraphicsState( accessorHeader.StateFlags.HasFlag(GuestGpuStateFlags.EarlyZForce), topology, - tessMode); + tessMode, + false); TransformFeedbackDescriptor[] tfdNew = null; diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs index b1c04eac..bc63f714 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs @@ -185,6 +185,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache return _oldSpecState.GraphicsState.EarlyZForce; } + /// + public bool QueryViewportTransformDisable() + { + return _oldSpecState.GraphicsState.ViewportTransformDisable; + } + /// public void RegisterTexture(int handle, int cbufSlot) { diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 0028e879..5d99957f 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 1; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 0; + private const uint CodeGenVersion = 1; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index 192467b7..5cd966af 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -217,6 +217,12 @@ namespace Ryujinx.Graphics.Gpu.Shader return _state.GraphicsState.EarlyZForce; } + /// + public bool QueryViewportTransformDisable() + { + return _state.GraphicsState.ViewportTransformDisable; + } + /// public void RegisterTexture(int handle, int cbufSlot) { diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs index 5eb31db6..92ec117f 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs @@ -25,17 +25,24 @@ namespace Ryujinx.Graphics.Gpu.Shader /// public readonly TessMode TessellationMode; + /// + /// Indicates whenever the viewport transform is disabled. + /// + public readonly bool ViewportTransformDisable; + /// /// Creates a new GPU graphics state. /// /// Early Z force enable /// Primitive topology /// Tessellation mode - public GpuChannelGraphicsState(bool earlyZForce, PrimitiveTopology topology, TessMode tessellationMode) + /// Indicates whenever the viewport transform is disabled + public GpuChannelGraphicsState(bool earlyZForce, PrimitiveTopology topology, TessMode tessellationMode, bool viewportTransformDisable) { EarlyZForce = earlyZForce; Topology = topology; TessellationMode = tessellationMode; + ViewportTransformDisable = viewportTransformDisable; } } } \ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 03d5ecad..df4b9d12 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -249,12 +249,12 @@ namespace Ryujinx.Graphics.Gpu.Shader GpuChannelGraphicsState graphicsState, ShaderAddresses addresses) { - if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, poolState, gpShaders, addresses)) + if (_gpPrograms.TryGetValue(addresses, out var gpShaders) && IsShaderEqual(channel, poolState, graphicsState, gpShaders, addresses)) { return gpShaders; } - if (_graphicsShaderCache.TryFind(channel, poolState, addresses, out gpShaders, out var cachedGuestCode)) + if (_graphicsShaderCache.TryFind(channel, poolState, graphicsState, addresses, out gpShaders, out var cachedGuestCode)) { _gpPrograms[addresses] = gpShaders; return gpShaders; @@ -429,12 +429,14 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// GPU channel using the shader /// GPU channel state to verify shader compatibility + /// GPU channel graphics state to verify shader compatibility /// Cached graphics shaders /// GPU virtual addresses of all enabled shader stages /// True if the code is different, false otherwise private static bool IsShaderEqual( GpuChannel channel, GpuChannelPoolState poolState, + GpuChannelGraphicsState graphicsState, CachedShaderProgram gpShaders, ShaderAddresses addresses) { @@ -452,7 +454,7 @@ namespace Ryujinx.Graphics.Gpu.Shader } } - return gpShaders.SpecializationState.MatchesGraphics(channel, poolState); + return gpShaders.SpecializationState.MatchesGraphics(channel, poolState, graphicsState); } /// diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs index 065f9ba9..3d74e53a 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCacheHashTable.cs @@ -208,6 +208,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// GPU channel /// Texture pool state + /// Graphics state /// Guest addresses of the shaders to find /// Cached host program for the given state, if found /// Cached guest code, if any found @@ -215,6 +216,7 @@ namespace Ryujinx.Graphics.Gpu.Shader public bool TryFind( GpuChannel channel, GpuChannelPoolState poolState, + GpuChannelGraphicsState graphicsState, ShaderAddresses addresses, out CachedShaderProgram program, out CachedGraphicsGuestCode guestCode) @@ -234,7 +236,7 @@ namespace Ryujinx.Graphics.Gpu.Shader if (found && _shaderPrograms.TryGetValue(idTable, out ShaderSpecializationList specList)) { - return specList.TryFindForGraphics(channel, poolState, out program); + return specList.TryFindForGraphics(channel, poolState, graphicsState, out program); } return false; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs index 87e08754..e3e57d74 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs @@ -24,13 +24,18 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// GPU channel /// Texture pool state + /// Graphics state /// Cached program, if found /// True if a compatible program is found, false otherwise - public bool TryFindForGraphics(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program) + public bool TryFindForGraphics( + GpuChannel channel, + GpuChannelPoolState poolState, + GpuChannelGraphicsState graphicsState, + out CachedShaderProgram program) { foreach (var entry in _entries) { - if (entry.SpecializationState.MatchesGraphics(channel, poolState)) + if (entry.SpecializationState.MatchesGraphics(channel, poolState, graphicsState)) { program = entry; return true; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index 2bbc3d2c..418c7b1a 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -395,9 +395,15 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// GPU channel /// Texture pool state + /// Graphics state /// True if the state matches, false otherwise - public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState) + public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelGraphicsState graphicsState) { + if (graphicsState.ViewportTransformDisable != GraphicsState.ViewportTransformDisable) + { + return false; + } + return Matches(channel, poolState, isCompute: false); } -- cgit v1.2.3