diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2022-12-04 17:18:40 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-04 18:18:40 +0100 |
| commit | 4965681e069eeedc5272030b131c2a45e6131e61 (patch) | |
| tree | 050a6596728c6a040c5c17fd21339c913b97ee8f /Ryujinx.Graphics.Gpu/Shader | |
| parent | 3868a0020611491e30db19e5b27d33a7559c7071 (diff) | |
GPU: Swap bindings array instead of copying (#4003)
* GPU: Swap bindings array instead of copying
Reduces work on UpdateShaderState. Now the cost is a few reference moves for arrays, rather than copying data.
Downside: bindings arrays are no longer readonly.
* Micro optimisation
* Add missing docs
* Address Feedback
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs | 103 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs | 6 |
2 files changed, 109 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs b/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs new file mode 100644 index 00000000..1734f08a --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs @@ -0,0 +1,103 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Gpu.Engine; +using Ryujinx.Graphics.Gpu.Image; +using Ryujinx.Graphics.Shader; +using System; +using System.Linq; + +namespace Ryujinx.Graphics.Gpu.Shader +{ + /// <summary> + /// A collection of shader bindings ready for insertion into the buffer and texture managers. + /// </summary> + internal class CachedShaderBindings + { + public TextureBindingInfo[][] TextureBindings { get; } + public TextureBindingInfo[][] ImageBindings { get; } + public BufferDescriptor[][] ConstantBufferBindings { get; } + public BufferDescriptor[][] StorageBufferBindings { get; } + + public int MaxTextureBinding { get; } + public int MaxImageBinding { get; } + + /// <summary> + /// Create a new cached shader bindings collection. + /// </summary> + /// <param name="isCompute">Whether the shader is for compute</param> + /// <param name="stages">The stages used by the shader</param> + public CachedShaderBindings(bool isCompute, CachedShaderStage[] stages) + { + int stageCount = isCompute ? 1 : Constants.ShaderStages; + + TextureBindings = new TextureBindingInfo[stageCount][]; + ImageBindings = new TextureBindingInfo[stageCount][]; + ConstantBufferBindings = new BufferDescriptor[stageCount][]; + StorageBufferBindings = new BufferDescriptor[stageCount][]; + + int maxTextureBinding = -1; + int maxImageBinding = -1; + int offset = isCompute ? 0 : 1; + + for (int i = 0; i < stageCount; i++) + { + CachedShaderStage stage = stages[i + offset]; + + if (stage == null) + { + TextureBindings[i] = Array.Empty<TextureBindingInfo>(); + ImageBindings[i] = Array.Empty<TextureBindingInfo>(); + ConstantBufferBindings[i] = Array.Empty<BufferDescriptor>(); + StorageBufferBindings[i] = Array.Empty<BufferDescriptor>(); + + continue; + } + + TextureBindings[i] = stage.Info.Textures.Select(descriptor => + { + Target target = ShaderTexture.GetTarget(descriptor.Type); + + var result = new TextureBindingInfo( + target, + descriptor.Binding, + descriptor.CbufSlot, + descriptor.HandleIndex, + descriptor.Flags); + + if (descriptor.Binding > maxTextureBinding) + { + maxTextureBinding = descriptor.Binding; + } + + return result; + }).ToArray(); + + ImageBindings[i] = stage.Info.Images.Select(descriptor => + { + Target target = ShaderTexture.GetTarget(descriptor.Type); + Format format = ShaderTexture.GetFormat(descriptor.Format); + + var result = new TextureBindingInfo( + target, + format, + descriptor.Binding, + descriptor.CbufSlot, + descriptor.HandleIndex, + descriptor.Flags); + + if (descriptor.Binding > maxImageBinding) + { + maxImageBinding = descriptor.Binding; + } + + return result; + }).ToArray(); + + ConstantBufferBindings[i] = stage.Info.CBuffers.ToArray(); + StorageBufferBindings[i] = stage.Info.SBuffers.ToArray(); + } + + MaxTextureBinding = maxTextureBinding; + MaxImageBinding = maxImageBinding; + } + } +} diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs b/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs index 69fcb278..ff9c39a1 100644 --- a/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs +++ b/Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs @@ -25,6 +25,11 @@ namespace Ryujinx.Graphics.Gpu.Shader public CachedShaderStage[] Shaders { get; } /// <summary> + /// Cached shader bindings, ready for placing into the bindings manager. + /// </summary> + public CachedShaderBindings Bindings { get; } + + /// <summary> /// Creates a new instance of the shader bundle. /// </summary> /// <param name="hostProgram">Host program with all the shader stages</param> @@ -37,6 +42,7 @@ namespace Ryujinx.Graphics.Gpu.Shader Shaders = shaders; SpecializationState.Prepare(shaders); + Bindings = new CachedShaderBindings(shaders.Length == 1, shaders); } /// <summary> |
