Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
StreamOutputParser.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if PARADOX_EFFECT_COMPILER
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using System.Text.RegularExpressions;
8 
9 using SiliconStudio.Shaders.Ast;
10 using SiliconStudio.Shaders.Ast.Hlsl;
11 using SiliconStudio.Paradox.Graphics;
12 
13 namespace SiliconStudio.Paradox.Shaders.Parser.Mixins
14 {
15  public static class StreamOutputParser
16  {
17  private static Regex streamOutputRegex = new Regex(@"(([0-9]*)\s*:\s*)?(\w+)(.(\w+))?");
18  private static readonly string[] masks = new[] { "xyzw", "rgba", "stuv" };
19 
20  public static void Parse(IList<ShaderStreamOutputDeclarationEntry> entries, out int[] strides, AttributeDeclaration streamOutputAttribute, IList<Variable> fields)
21  {
22  var streamStrings = streamOutputAttribute.Parameters
23  .TakeWhile(x => x.Value is string)
24  .Select(x => x.Value as string)
25  .ToArray();
26 
27  Parse(entries, out strides, streamStrings, fields);
28  }
29 
30  /// <summary>
31  /// Parse stream output declarations.
32  /// Format is "[slot :] semantic[index][.mask] ; ...".
33  /// </summary>
34  /// <param name="entries">The parsed entries.</param>
35  /// <param name="strides">The output strides.</param>
36  /// <param name="streams">The output declarations to parse.</param>
37  public static void Parse(IList<ShaderStreamOutputDeclarationEntry> entries, out int[] strides, string[] streams, IList<Variable> fields)
38  {
39  strides = new int[4];
40 
41  var fieldsBySemantic = fields.ToDictionary(x => Semantic.Parse(x.Qualifiers.OfType<Semantic>().Single().Name));
42 
43  for (int streamIndex = 0; streamIndex < streams.Length; ++streamIndex)
44  {
45  // Parse multiple declarations separated by semicolon
46  var stream = streams[streamIndex];
47  foreach (var streamOutput in stream.Split(';'))
48  {
49  // Parse a single declaration: "[slot :] semantic[index][.mask]"
50  var match = streamOutputRegex.Match(streamOutput);
51  if (!match.Success)
52  throw new InvalidOperationException("Could not parse stream output.");
53 
54  var streamOutputDecl = new ShaderStreamOutputDeclarationEntry();
55 
56  // Split semantic into (name, index)
57  var semantic = Semantic.Parse(match.Groups[3].Value);
58 
59  streamOutputDecl.SemanticName = semantic.Key;
60  streamOutputDecl.SemanticIndex = semantic.Value;
61  //if (streamOutputDecl.SemanticName == "$SKIP")
62  // streamOutputDecl.SemanticName = null;
63 
64  var matchingField = fieldsBySemantic[semantic];
65  var matchingFieldType = matchingField.Type.TypeInference.TargetType ?? matchingField.Type;
66 
67  if (matchingFieldType is VectorType)
68  streamOutputDecl.ComponentCount = (byte)((VectorType)matchingFieldType).Dimension;
69  else if (matchingFieldType is ScalarType)
70  streamOutputDecl.ComponentCount = 1;
71  else
72  throw new InvalidOperationException(string.Format("Could not recognize type of stream output for {0}.", matchingField));
73 
74  var mask = match.Groups[5].Value;
75  ParseMask(mask, ref streamOutputDecl.StartComponent, ref streamOutputDecl.ComponentCount);
76 
77  byte.TryParse(match.Groups[2].Value, out streamOutputDecl.OutputSlot);
78 
79  streamOutputDecl.Stream = streamIndex;
80 
81  strides[streamOutputDecl.OutputSlot] += streamOutputDecl.ComponentCount * sizeof(float);
82  entries.Add(streamOutputDecl);
83  }
84  }
85  }
86 
87  private static bool ParseMask(string mask, ref byte startComponent, ref byte componentCount)
88  {
89  if (mask == string.Empty)
90  {
91  return false;
92  }
93 
94  foreach (var maskRef in masks)
95  {
96  var index = maskRef.IndexOf(mask);
97  if (index != -1)
98  {
99  componentCount = (byte)mask.Length;
100  startComponent = (byte)index;
101  return true;
102  }
103  }
104 
105  throw new InvalidOperationException("Could not parse stream output mask.");
106  }
107  }
108 }
109 #endif
Gets a single texture view at the specified index in the mip hierarchy and in the array of textures T...