3 #if PARADOX_EFFECT_COMPILER
5 using System.Collections.Generic;
7 using System.Text.RegularExpressions;
9 using SiliconStudio.Shaders.Ast;
10 using SiliconStudio.Shaders.Ast.Hlsl;
11 using SiliconStudio.Paradox.Graphics;
13 namespace SiliconStudio.
Paradox.Shaders.Parser.Mixins
15 public static class StreamOutputParser
17 private static Regex streamOutputRegex =
new Regex(
@"(([0-9]*)\s*:\s*)?(\w+)(.(\w+))?");
18 private static readonly
string[] masks =
new[] {
"xyzw",
"rgba",
"stuv" };
20 public static void Parse(IList<ShaderStreamOutputDeclarationEntry> entries, out
int[] strides, AttributeDeclaration streamOutputAttribute, IList<Variable> fields)
22 var streamStrings = streamOutputAttribute.Parameters
23 .TakeWhile(x => x.Value is string)
24 .
Select(x => x.Value as
string)
27 Parse(entries, out strides, streamStrings, fields);
37 public static void Parse(IList<ShaderStreamOutputDeclarationEntry> entries, out
int[] strides,
string[] streams, IList<Variable> fields)
41 var fieldsBySemantic = fields.ToDictionary(x => Semantic.Parse(x.Qualifiers.OfType<Semantic>().
Single().Name));
43 for (
int streamIndex = 0; streamIndex < streams.Length; ++streamIndex)
46 var stream = streams[streamIndex];
47 foreach (var streamOutput
in stream.Split(
';'))
50 var match = streamOutputRegex.Match(streamOutput);
52 throw new InvalidOperationException(
"Could not parse stream output.");
54 var streamOutputDecl =
new ShaderStreamOutputDeclarationEntry();
57 var semantic = Semantic.Parse(match.Groups[3].Value);
59 streamOutputDecl.SemanticName = semantic.Key;
60 streamOutputDecl.SemanticIndex = semantic.Value;
64 var matchingField = fieldsBySemantic[semantic];
65 var matchingFieldType = matchingField.Type.TypeInference.TargetType ?? matchingField.Type;
67 if (matchingFieldType is VectorType)
68 streamOutputDecl.ComponentCount = (byte)((VectorType)matchingFieldType).Dimension;
69 else if (matchingFieldType is ScalarType)
70 streamOutputDecl.ComponentCount = 1;
72 throw new InvalidOperationException(
string.Format(
"Could not recognize type of stream output for {0}.", matchingField));
74 var mask = match.Groups[5].Value;
75 ParseMask(mask, ref streamOutputDecl.StartComponent, ref streamOutputDecl.ComponentCount);
77 byte.TryParse(match.Groups[2].Value, out streamOutputDecl.OutputSlot);
79 streamOutputDecl.Stream = streamIndex;
81 strides[streamOutputDecl.OutputSlot] += streamOutputDecl.ComponentCount *
sizeof(float);
82 entries.Add(streamOutputDecl);
87 private static bool ParseMask(
string mask, ref byte startComponent, ref byte componentCount)
89 if (mask ==
string.Empty)
94 foreach (var maskRef
in masks)
96 var index = maskRef.IndexOf(mask);
99 componentCount = (byte)mask.Length;
100 startComponent = (byte)index;
105 throw new InvalidOperationException(
"Could not parse stream output mask.");
Gets a single texture view at the specified index in the mip hierarchy and in the array of textures T...