using System.Collections.Generic; namespace Ryujinx.Graphics.Shader.StructuredIr { readonly struct TransformFeedbackOutput { public readonly bool Valid; public readonly int Buffer; public readonly int Offset; public readonly int Stride; public TransformFeedbackOutput(int buffer, int offset, int stride) { Valid = true; Buffer = buffer; Offset = offset; Stride = stride; } } class StructuredProgramInfo { public List Functions { get; } public HashSet Inputs { get; } public HashSet Outputs { get; } public HashSet InputsPerPatch { get; } public HashSet OutputsPerPatch { get; } public HelperFunctionsMask HelperFunctionsMask { get; set; } public TransformFeedbackOutput[] TransformFeedbackOutputs { get; } public StructuredProgramInfo() { Functions = new List(); Inputs = new HashSet(); Outputs = new HashSet(); InputsPerPatch = new HashSet(); OutputsPerPatch = new HashSet(); TransformFeedbackOutputs = new TransformFeedbackOutput[0xc0]; } public TransformFeedbackOutput GetTransformFeedbackOutput(int attr) { int index = attr / 4; return TransformFeedbackOutputs[index]; } public int GetTransformFeedbackOutputComponents(int attr) { int index = attr / 4; int baseIndex = index & ~3; int count = 1; for (; count < 4; count++) { ref var prev = ref TransformFeedbackOutputs[baseIndex + count - 1]; ref var curr = ref TransformFeedbackOutputs[baseIndex + count]; int prevOffset = prev.Offset; int currOffset = curr.Offset; if (!prev.Valid || !curr.Valid || prevOffset + 4 != currOffset) { break; } } if (baseIndex + count <= index) { return 1; } return count; } } }