コード例 #1
0
ファイル: StreamOutputParser.cs プロジェクト: Aggror/Stride
        /// <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);
                }
            }
        }
コード例 #2
0
        /// <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);
                }
            }
        }