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
This commit is contained in:
parent
3868a00206
commit
4965681e06
7 changed files with 162 additions and 252 deletions
103
Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs
Normal file
103
Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue