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 }