/ src / Ryujinx.Graphics.Shader / SupportBuffer.cs
SupportBuffer.cs
  1  using Ryujinx.Common.Memory;
  2  using Ryujinx.Graphics.Shader.StructuredIr;
  3  using Ryujinx.Graphics.Shader.Translation;
  4  using System.Runtime.CompilerServices;
  5  
  6  namespace Ryujinx.Graphics.Shader
  7  {
  8      public struct Vector4<T>
  9      {
 10          public T X;
 11          public T Y;
 12          public T Z;
 13          public T W;
 14      }
 15  
 16      enum SupportBufferField
 17      {
 18          // Must match the order of the fields on the struct.
 19          FragmentAlphaTest,
 20          FragmentIsBgra,
 21          ViewportInverse,
 22          ViewportSize,
 23          FragmentRenderScaleCount,
 24          RenderScale,
 25          TfeOffset,
 26          TfeVertexCount,
 27      }
 28  
 29      public struct SupportBuffer
 30      {
 31          public const int Binding = 0;
 32  
 33          public static readonly int FieldSize;
 34          public static readonly int RequiredSize;
 35  
 36          public static readonly int FragmentAlphaTestOffset;
 37          public static readonly int FragmentIsBgraOffset;
 38          public static readonly int ViewportInverseOffset;
 39          public static readonly int ViewportSizeOffset;
 40          public static readonly int FragmentRenderScaleCountOffset;
 41          public static readonly int GraphicsRenderScaleOffset;
 42          public static readonly int ComputeRenderScaleOffset;
 43          public static readonly int TfeOffsetOffset;
 44          public static readonly int TfeVertexCountOffset;
 45  
 46          public const int FragmentIsBgraCount = 8;
 47          // One for the render target, 64 for the textures, and 8 for the images.
 48          public const int RenderScaleMaxCount = 1 + 64 + 8;
 49  
 50          private static int OffsetOf<T>(ref SupportBuffer storage, ref T target)
 51          {
 52              return (int)Unsafe.ByteOffset(ref Unsafe.As<SupportBuffer, T>(ref storage), ref target);
 53          }
 54  
 55          static SupportBuffer()
 56          {
 57              FieldSize = Unsafe.SizeOf<Vector4<float>>();
 58              RequiredSize = Unsafe.SizeOf<SupportBuffer>();
 59  
 60              SupportBuffer instance = new();
 61  
 62              FragmentAlphaTestOffset = OffsetOf(ref instance, ref instance.FragmentAlphaTest);
 63              FragmentIsBgraOffset = OffsetOf(ref instance, ref instance.FragmentIsBgra);
 64              ViewportInverseOffset = OffsetOf(ref instance, ref instance.ViewportInverse);
 65              ViewportSizeOffset = OffsetOf(ref instance, ref instance.ViewportSize);
 66              FragmentRenderScaleCountOffset = OffsetOf(ref instance, ref instance.FragmentRenderScaleCount);
 67              GraphicsRenderScaleOffset = OffsetOf(ref instance, ref instance.RenderScale);
 68              ComputeRenderScaleOffset = GraphicsRenderScaleOffset + FieldSize;
 69              TfeOffsetOffset = OffsetOf(ref instance, ref instance.TfeOffset);
 70              TfeVertexCountOffset = OffsetOf(ref instance, ref instance.TfeVertexCount);
 71          }
 72  
 73          internal static StructureType GetStructureType()
 74          {
 75              return new StructureType(new[]
 76              {
 77                  new StructureField(AggregateType.U32, "alpha_test"),
 78                  new StructureField(AggregateType.Array | AggregateType.U32, "is_bgra", FragmentIsBgraCount),
 79                  new StructureField(AggregateType.Vector4 | AggregateType.FP32, "viewport_inverse"),
 80                  new StructureField(AggregateType.Vector4 | AggregateType.FP32, "viewport_size"),
 81                  new StructureField(AggregateType.S32, "frag_scale_count"),
 82                  new StructureField(AggregateType.Array | AggregateType.FP32, "render_scale", RenderScaleMaxCount),
 83                  new StructureField(AggregateType.Vector4 | AggregateType.S32, "tfe_offset"),
 84                  new StructureField(AggregateType.S32, "tfe_vertex_count"),
 85              });
 86          }
 87  
 88          public Vector4<int> FragmentAlphaTest;
 89          public Array8<Vector4<int>> FragmentIsBgra;
 90          public Vector4<float> ViewportInverse;
 91          public Vector4<float> ViewportSize;
 92          public Vector4<int> FragmentRenderScaleCount;
 93  
 94          // Render scale max count: 1 + 64 + 8. First scale is fragment output scale, others are textures/image inputs.
 95          public Array73<Vector4<float>> RenderScale;
 96  
 97          public Vector4<int> TfeOffset;
 98          public Vector4<int> TfeVertexCount;
 99      }
100  }