aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Shader
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2022-12-04 17:18:40 +0000
committerGitHub <noreply@github.com>2022-12-04 18:18:40 +0100
commit4965681e069eeedc5272030b131c2a45e6131e61 (patch)
tree050a6596728c6a040c5c17fd21339c913b97ee8f /Ryujinx.Graphics.Gpu/Shader
parent3868a0020611491e30db19e5b27d33a7559c7071 (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.cs103
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/CachedShaderProgram.cs6
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>