diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2022-11-17 17:47:41 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-17 18:47:41 +0100 |
| commit | 33a4d7d1badbebd2dc05114ef17c85678baed843 (patch) | |
| tree | dbf7fd4adb24d59a5adceca6c0cc36099064f917 /Ryujinx.Graphics.Gpu/Shader | |
| parent | 391e08dd27661b72674f91450ac00d1363938251 (diff) | |
GPU: Eliminate CB0 accesses when storage buffer accesses are resolved (#3847)
* Eliminate CB0 accesses
Still some work to do, decouple from hle?
* Forgot the important part somehow
* Fix and improve alignment test
* Address Feedback
* Remove some complexity when checking storage buffer alignment
* Update Ryujinx.Graphics.Shader/Translation/Optimizations/GlobalToStorage.cs
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader')
9 files changed, 54 insertions, 10 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ComputeShaderCacheHashTable.cs b/Ryujinx.Graphics.Gpu/Shader/ComputeShaderCacheHashTable.cs index 08154df3..a6718211 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ComputeShaderCacheHashTable.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ComputeShaderCacheHashTable.cs @@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> + /// <param name="computeState">Compute state</param> /// <param name="gpuVa">GPU virtual address of the compute shader</param> /// <param name="program">Cached host program for the given state, if found</param> /// <param name="cachedGuestCode">Cached guest code, if any found</param> @@ -43,6 +44,7 @@ namespace Ryujinx.Graphics.Gpu.Shader public bool TryFind( GpuChannel channel, GpuChannelPoolState poolState, + GpuChannelComputeState computeState, ulong gpuVa, out CachedShaderProgram program, out byte[] cachedGuestCode) @@ -50,7 +52,7 @@ namespace Ryujinx.Graphics.Gpu.Shader program = null; ShaderCodeAccessor codeAccessor = new ShaderCodeAccessor(channel.MemoryManager, gpuVa); bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode); - return hasSpecList && specList.TryFindForCompute(channel, poolState, out program); + return hasSpecList && specList.TryFindForCompute(channel, poolState, computeState, out program); } /// <summary> diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs index 98748bf6..c567c2c0 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheGpuAccessor.cs @@ -226,6 +226,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache } /// <inheritdoc/> + public bool QueryHasUnalignedStorageBuffer() + { + return _oldSpecState.GraphicsState.HasUnalignedStorageBuffer || _oldSpecState.ComputeState.HasUnalignedStorageBuffer; + } + + /// <inheritdoc/> public bool QueryViewportTransformDisable() { return _oldSpecState.GraphicsState.ViewportTransformDisable; diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 0bdf4949..e23b4d50 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 3747; + private const uint CodeGenVersion = 3848; 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 b8cb1107..28ea430c 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -146,6 +146,12 @@ namespace Ryujinx.Graphics.Gpu.Shader } /// <inheritdoc/> + public bool QueryHasUnalignedStorageBuffer() + { + return _state.GraphicsState.HasUnalignedStorageBuffer || _state.ComputeState.HasUnalignedStorageBuffer; + } + + /// <inheritdoc/> public InputTopology QueryPrimitiveTopology() { _state.SpecializationState?.RecordPrimitiveTopology(); diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs index 89a3db71..356d3f3e 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuChannelComputeState.cs @@ -33,6 +33,11 @@ namespace Ryujinx.Graphics.Gpu.Shader public readonly int SharedMemorySize; /// <summary> + /// Indicates that any storage buffer use is unaligned. + /// </summary> + public readonly bool HasUnalignedStorageBuffer; + + /// <summary> /// Creates a new GPU compute state. /// </summary> /// <param name="localSizeX">Local group size X of the compute shader</param> @@ -40,18 +45,21 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="localSizeZ">Local group size Z of the compute shader</param> /// <param name="localMemorySize">Local memory size of the compute shader</param> /// <param name="sharedMemorySize">Shared memory size of the compute shader</param> + /// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param> public GpuChannelComputeState( int localSizeX, int localSizeY, int localSizeZ, int localMemorySize, - int sharedMemorySize) + int sharedMemorySize, + bool hasUnalignedStorageBuffer) { LocalSizeX = localSizeX; LocalSizeY = localSizeY; LocalSizeZ = localSizeZ; LocalMemorySize = localMemorySize; SharedMemorySize = sharedMemorySize; + HasUnalignedStorageBuffer = hasUnalignedStorageBuffer; } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs index b0727677..511f4c23 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuChannelGraphicsState.cs @@ -83,6 +83,11 @@ namespace Ryujinx.Graphics.Gpu.Shader public readonly bool HasConstantBufferDrawParameters; /// <summary> + /// Indicates that any storage buffer use is unaligned. + /// </summary> + public readonly bool HasUnalignedStorageBuffer; + + /// <summary> /// Creates a new GPU graphics state. /// </summary> /// <param name="earlyZForce">Early Z force enable</param> @@ -99,6 +104,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <param name="alphaTestReference">When alpha test is enabled, indicates the value to compare with the fragment output alpha</param> /// <param name="attributeTypes">Type of the vertex attributes consumed by the shader</param> /// <param name="hasConstantBufferDrawParameters">Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0</param> + /// <param name="hasUnalignedStorageBuffer">Indicates that any storage buffer use is unaligned</param> public GpuChannelGraphicsState( bool earlyZForce, PrimitiveTopology topology, @@ -113,7 +119,8 @@ namespace Ryujinx.Graphics.Gpu.Shader CompareOp alphaTestCompare, float alphaTestReference, ref Array32<AttributeType> attributeTypes, - bool hasConstantBufferDrawParameters) + bool hasConstantBufferDrawParameters, + bool hasUnalignedStorageBuffer) { EarlyZForce = earlyZForce; Topology = topology; @@ -129,6 +136,7 @@ namespace Ryujinx.Graphics.Gpu.Shader AlphaTestReference = alphaTestReference; AttributeTypes = attributeTypes; HasConstantBufferDrawParameters = hasConstantBufferDrawParameters; + HasUnalignedStorageBuffer = hasUnalignedStorageBuffer; } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 1803dae6..2a9dd6a5 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -203,12 +203,12 @@ namespace Ryujinx.Graphics.Gpu.Shader GpuChannelComputeState computeState, ulong gpuVa) { - if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, cpShader, gpuVa)) + if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, computeState, cpShader, gpuVa)) { return cpShader; } - if (_computeShaderCache.TryFind(channel, poolState, gpuVa, out cpShader, out byte[] cachedGuestCode)) + if (_computeShaderCache.TryFind(channel, poolState, computeState, gpuVa, out cpShader, out byte[] cachedGuestCode)) { _cpPrograms[gpuVa] = cpShader; return cpShader; @@ -473,18 +473,20 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="channel">GPU channel using the shader</param> /// <param name="poolState">GPU channel state to verify shader compatibility</param> + /// <param name="computeState">GPU channel compute state to verify shader compatibility</param> /// <param name="cpShader">Cached compute shader</param> /// <param name="gpuVa">GPU virtual address of the shader code in memory</param> /// <returns>True if the code is different, false otherwise</returns> private static bool IsShaderEqual( GpuChannel channel, GpuChannelPoolState poolState, + GpuChannelComputeState computeState, CachedShaderProgram cpShader, ulong gpuVa) { if (IsShaderEqual(channel.MemoryManager, cpShader.Shaders[0], gpuVa)) { - return cpShader.SpecializationState.MatchesCompute(channel, poolState, true); + return cpShader.SpecializationState.MatchesCompute(channel, poolState, computeState, true); } return false; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs index abc9d913..cb6ab49a 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationList.cs @@ -53,13 +53,14 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> + /// <param name="computeState">Compute state</param> /// <param name="program">Cached program, if found</param> /// <returns>True if a compatible program is found, false otherwise</returns> - public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program) + public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, out CachedShaderProgram program) { foreach (var entry in _entries) { - if (entry.SpecializationState.MatchesCompute(channel, poolState, true)) + if (entry.SpecializationState.MatchesCompute(channel, poolState, computeState, true)) { program = entry; return true; diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index 0aecc5b7..8f931507 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -531,6 +531,11 @@ namespace Ryujinx.Graphics.Gpu.Shader return false; } + if (graphicsState.HasUnalignedStorageBuffer != GraphicsState.HasUnalignedStorageBuffer) + { + return false; + } + return Matches(channel, poolState, checkTextures, isCompute: false); } @@ -539,10 +544,16 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> + /// <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, bool checkTextures) + public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, bool checkTextures) { + if (computeState.HasUnalignedStorageBuffer != ComputeState.HasUnalignedStorageBuffer) + { + return false; + } + return Matches(channel, poolState, checkTextures, isCompute: true); } |
