/ src / Ryujinx.Graphics.Gpu / Shader / CachedShaderBindings.cs
CachedShaderBindings.cs
  1  using Ryujinx.Graphics.GAL;
  2  using Ryujinx.Graphics.Gpu.Engine;
  3  using Ryujinx.Graphics.Gpu.Image;
  4  using Ryujinx.Graphics.Shader;
  5  using System;
  6  using System.Linq;
  7  
  8  namespace Ryujinx.Graphics.Gpu.Shader
  9  {
 10      /// <summary>
 11      /// A collection of shader bindings ready for insertion into the buffer and texture managers.
 12      /// </summary>
 13      internal class CachedShaderBindings
 14      {
 15          public TextureBindingInfo[][] TextureBindings { get; }
 16          public TextureBindingInfo[][] ImageBindings { get; }
 17          public BufferDescriptor[][] ConstantBufferBindings { get; }
 18          public BufferDescriptor[][] StorageBufferBindings { get; }
 19  
 20          public int[] TextureCounts { get; }
 21  
 22          public int MaxTextureBinding { get; }
 23          public int MaxImageBinding { get; }
 24  
 25          /// <summary>
 26          /// Create a new cached shader bindings collection.
 27          /// </summary>
 28          /// <param name="isCompute">Whether the shader is for compute</param>
 29          /// <param name="stages">The stages used by the shader</param>
 30          public CachedShaderBindings(bool isCompute, CachedShaderStage[] stages)
 31          {
 32              int stageCount = isCompute ? 1 : Constants.ShaderStages;
 33  
 34              TextureBindings = new TextureBindingInfo[stageCount][];
 35              ImageBindings = new TextureBindingInfo[stageCount][];
 36              ConstantBufferBindings = new BufferDescriptor[stageCount][];
 37              StorageBufferBindings = new BufferDescriptor[stageCount][];
 38  
 39              TextureCounts = new int[stageCount];
 40  
 41              int maxTextureBinding = -1;
 42              int maxImageBinding = -1;
 43              int offset = isCompute ? 0 : 1;
 44  
 45              for (int i = 0; i < stageCount; i++)
 46              {
 47                  CachedShaderStage stage = stages[i + offset];
 48  
 49                  if (stage == null)
 50                  {
 51                      TextureBindings[i] = Array.Empty<TextureBindingInfo>();
 52                      ImageBindings[i] = Array.Empty<TextureBindingInfo>();
 53                      ConstantBufferBindings[i] = Array.Empty<BufferDescriptor>();
 54                      StorageBufferBindings[i] = Array.Empty<BufferDescriptor>();
 55  
 56                      continue;
 57                  }
 58  
 59                  TextureBindings[i] = stage.Info.Textures.Select(descriptor =>
 60                  {
 61                      Target target = descriptor.Type != SamplerType.None ? ShaderTexture.GetTarget(descriptor.Type) : default;
 62  
 63                      var result = new TextureBindingInfo(
 64                          target,
 65                          descriptor.Set,
 66                          descriptor.Binding,
 67                          descriptor.ArrayLength,
 68                          descriptor.CbufSlot,
 69                          descriptor.HandleIndex,
 70                          descriptor.Flags,
 71                          descriptor.Type == SamplerType.None);
 72  
 73                      if (descriptor.ArrayLength <= 1)
 74                      {
 75                          if (descriptor.Binding > maxTextureBinding)
 76                          {
 77                              maxTextureBinding = descriptor.Binding;
 78                          }
 79  
 80                          TextureCounts[i]++;
 81                      }
 82  
 83                      return result;
 84                  }).ToArray();
 85  
 86                  ImageBindings[i] = stage.Info.Images.Select(descriptor =>
 87                  {
 88                      Target target = ShaderTexture.GetTarget(descriptor.Type);
 89                      FormatInfo formatInfo = ShaderTexture.GetFormatInfo(descriptor.Format);
 90  
 91                      var result = new TextureBindingInfo(
 92                          target,
 93                          formatInfo,
 94                          descriptor.Set,
 95                          descriptor.Binding,
 96                          descriptor.ArrayLength,
 97                          descriptor.CbufSlot,
 98                          descriptor.HandleIndex,
 99                          descriptor.Flags);
100  
101                      if (descriptor.ArrayLength <= 1 && descriptor.Binding > maxImageBinding)
102                      {
103                          maxImageBinding = descriptor.Binding;
104                      }
105  
106                      return result;
107                  }).ToArray();
108  
109                  ConstantBufferBindings[i] = stage.Info.CBuffers.ToArray();
110                  StorageBufferBindings[i] = stage.Info.SBuffers.ToArray();
111              }
112  
113              MaxTextureBinding = maxTextureBinding;
114              MaxImageBinding = maxImageBinding;
115          }
116      }
117  }