/// <summary> /// Parse stream output declarations. /// Format is "[slot :] semantic[index][.mask] ; ...". /// </summary> /// <param name="entries">The parsed entries.</param> /// <param name="strides">The output strides.</param> /// <param name="streams">The output declarations to parse.</param> public static void Parse(IList <ShaderStreamOutputDeclarationEntry> entries, out int[] strides, string[] streams, IList <Variable> fields) { strides = new int[4]; var fieldsBySemantic = fields.ToDictionary(x => Semantic.Parse(x.Qualifiers.OfType <Semantic>().Single().Name)); for (int streamIndex = 0; streamIndex < streams.Length; ++streamIndex) { // Parse multiple declarations separated by semicolon var stream = streams[streamIndex]; foreach (var streamOutput in stream.Split(';')) { // Parse a single declaration: "[slot :] semantic[index][.mask]" var match = streamOutputRegex.Match(streamOutput); if (!match.Success) { throw new InvalidOperationException("Could not parse stream output."); } var streamOutputDecl = new ShaderStreamOutputDeclarationEntry(); // Split semantic into (name, index) var semantic = Semantic.Parse(match.Groups[3].Value); streamOutputDecl.SemanticName = semantic.Key; streamOutputDecl.SemanticIndex = semantic.Value; //if (streamOutputDecl.SemanticName == "$SKIP") // streamOutputDecl.SemanticName = null; var matchingField = fieldsBySemantic[semantic]; var matchingFieldType = matchingField.Type.TypeInference.TargetType ?? matchingField.Type; if (matchingFieldType is VectorType) { streamOutputDecl.ComponentCount = (byte)((VectorType)matchingFieldType).Dimension; } else if (matchingFieldType is ScalarType) { streamOutputDecl.ComponentCount = 1; } else { throw new InvalidOperationException(string.Format("Could not recognize type of stream output for {0}.", matchingField)); } var mask = match.Groups[5].Value; ParseMask(mask, ref streamOutputDecl.StartComponent, ref streamOutputDecl.ComponentCount); byte.TryParse(match.Groups[2].Value, out streamOutputDecl.OutputSlot); streamOutputDecl.Stream = streamIndex; strides[streamOutputDecl.OutputSlot] += streamOutputDecl.ComponentCount * sizeof(float); entries.Add(streamOutputDecl); } } }
/// <summary> /// Parse stream output declarations. /// Format is "[slot :] semantic[index][.mask] ; ...". /// </summary> /// <param name="entries">The parsed entries.</param> /// <param name="strides">The output strides.</param> /// <param name="streams">The output declarations to parse.</param> public static void Parse(IList<ShaderStreamOutputDeclarationEntry> entries, out int[] strides, string[] streams, IList<Variable> fields) { strides = new int[4]; var fieldsBySemantic = fields.ToDictionary(x => Semantic.Parse(x.Qualifiers.OfType<Semantic>().Single().Name)); for (int streamIndex = 0; streamIndex < streams.Length; ++streamIndex) { // Parse multiple declarations separated by semicolon var stream = streams[streamIndex]; foreach (var streamOutput in stream.Split(';')) { // Parse a single declaration: "[slot :] semantic[index][.mask]" var match = streamOutputRegex.Match(streamOutput); if (!match.Success) throw new InvalidOperationException("Could not parse stream output."); var streamOutputDecl = new ShaderStreamOutputDeclarationEntry(); // Split semantic into (name, index) var semantic = Semantic.Parse(match.Groups[3].Value); streamOutputDecl.SemanticName = semantic.Key; streamOutputDecl.SemanticIndex = semantic.Value; //if (streamOutputDecl.SemanticName == "$SKIP") // streamOutputDecl.SemanticName = null; var matchingField = fieldsBySemantic[semantic]; var matchingFieldType = matchingField.Type.TypeInference.TargetType ?? matchingField.Type; if (matchingFieldType is VectorType) streamOutputDecl.ComponentCount = (byte)((VectorType)matchingFieldType).Dimension; else if (matchingFieldType is ScalarType) streamOutputDecl.ComponentCount = 1; else throw new InvalidOperationException(string.Format("Could not recognize type of stream output for {0}.", matchingField)); var mask = match.Groups[5].Value; ParseMask(mask, ref streamOutputDecl.StartComponent, ref streamOutputDecl.ComponentCount); byte.TryParse(match.Groups[2].Value, out streamOutputDecl.OutputSlot); streamOutputDecl.Stream = streamIndex; strides[streamOutputDecl.OutputSlot] += streamOutputDecl.ComponentCount * sizeof(float); entries.Add(streamOutputDecl); } } }