/ src / Ryujinx.Graphics.Shader / StructuredIr / ShaderProperties.cs
ShaderProperties.cs
  1  using System.Collections.Generic;
  2  
  3  namespace Ryujinx.Graphics.Shader.StructuredIr
  4  {
  5      class ShaderProperties
  6      {
  7          private readonly Dictionary<int, BufferDefinition> _constantBuffers;
  8          private readonly Dictionary<int, BufferDefinition> _storageBuffers;
  9          private readonly Dictionary<SetBindingPair, TextureDefinition> _textures;
 10          private readonly Dictionary<SetBindingPair, TextureDefinition> _images;
 11          private readonly Dictionary<int, MemoryDefinition> _localMemories;
 12          private readonly Dictionary<int, MemoryDefinition> _sharedMemories;
 13  
 14          public IReadOnlyDictionary<int, BufferDefinition> ConstantBuffers => _constantBuffers;
 15          public IReadOnlyDictionary<int, BufferDefinition> StorageBuffers => _storageBuffers;
 16          public IReadOnlyDictionary<SetBindingPair, TextureDefinition> Textures => _textures;
 17          public IReadOnlyDictionary<SetBindingPair, TextureDefinition> Images => _images;
 18          public IReadOnlyDictionary<int, MemoryDefinition> LocalMemories => _localMemories;
 19          public IReadOnlyDictionary<int, MemoryDefinition> SharedMemories => _sharedMemories;
 20  
 21          public ShaderProperties()
 22          {
 23              _constantBuffers = new Dictionary<int, BufferDefinition>();
 24              _storageBuffers = new Dictionary<int, BufferDefinition>();
 25              _textures = new Dictionary<SetBindingPair, TextureDefinition>();
 26              _images = new Dictionary<SetBindingPair, TextureDefinition>();
 27              _localMemories = new Dictionary<int, MemoryDefinition>();
 28              _sharedMemories = new Dictionary<int, MemoryDefinition>();
 29          }
 30  
 31          public void AddOrUpdateConstantBuffer(BufferDefinition definition)
 32          {
 33              _constantBuffers[definition.Binding] = definition;
 34          }
 35  
 36          public void AddOrUpdateStorageBuffer(BufferDefinition definition)
 37          {
 38              _storageBuffers[definition.Binding] = definition;
 39          }
 40  
 41          public void AddOrUpdateTexture(TextureDefinition definition)
 42          {
 43              _textures[new(definition.Set, definition.Binding)] = definition;
 44          }
 45  
 46          public void AddOrUpdateImage(TextureDefinition definition)
 47          {
 48              _images[new(definition.Set, definition.Binding)] = definition;
 49          }
 50  
 51          public int AddLocalMemory(MemoryDefinition definition)
 52          {
 53              int id = _localMemories.Count;
 54              _localMemories.Add(id, definition);
 55  
 56              return id;
 57          }
 58  
 59          public int AddSharedMemory(MemoryDefinition definition)
 60          {
 61              int id = _sharedMemories.Count;
 62              _sharedMemories.Add(id, definition);
 63  
 64              return id;
 65          }
 66  
 67          public static TextureFormat GetTextureFormat(IGpuAccessor gpuAccessor, int handle, int cbufSlot = -1)
 68          {
 69              // When the formatted load extension is supported, we don't need to
 70              // specify a format, we can just declare it without a format and the GPU will handle it.
 71              if (gpuAccessor.QueryHostSupportsImageLoadFormatted())
 72              {
 73                  return TextureFormat.Unknown;
 74              }
 75  
 76              var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
 77  
 78              if (format == TextureFormat.Unknown)
 79              {
 80                  gpuAccessor.Log($"Unknown format for texture {handle}.");
 81  
 82                  format = TextureFormat.R8G8B8A8Unorm;
 83              }
 84  
 85              return format;
 86          }
 87  
 88          private static bool FormatSupportsAtomic(TextureFormat format)
 89          {
 90              return format == TextureFormat.R32Sint || format == TextureFormat.R32Uint;
 91          }
 92  
 93          public static TextureFormat GetTextureFormatAtomic(IGpuAccessor gpuAccessor, int handle, int cbufSlot = -1)
 94          {
 95              // Atomic image instructions do not support GL_EXT_shader_image_load_formatted,
 96              // and must have a type specified. Default to R32Sint if not available.
 97  
 98              var format = gpuAccessor.QueryTextureFormat(handle, cbufSlot);
 99  
100              if (!FormatSupportsAtomic(format))
101              {
102                  gpuAccessor.Log($"Unsupported format for texture {handle}: {format}.");
103  
104                  format = TextureFormat.R32Sint;
105              }
106  
107              return format;
108          }
109      }
110  }