Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ShaderKeySourceGenerator.Partial.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 using System;
4 using System.Linq;
5 
6 using SiliconStudio.Paradox.Shaders.Parser.Ast;
7 using SiliconStudio.Shaders.Ast;
8 using SiliconStudio.Shaders.Ast.Hlsl;
9 using SiliconStudio.Shaders.Visitor;
10 
11 namespace SiliconStudio.Paradox.VisualStudio.Commands.Shaders
12 {
13  internal partial class ShaderKeySourceGenerator
14  {
15  public ShaderKeySourceGenerator(ShaderKeyClass shaderKeyClass)
16  {
17  this.ShaderKeyClass = shaderKeyClass;
18  }
19 
20  public ShaderKeyClass ShaderKeyClass { get; set; }
21 
22  internal static ShaderKeyClass GenerateShaderKeyClass(ShaderClassType shaderClassType)
23  {
24  ShaderKeyClass shaderKeyClass = null;
25 
26  // Iterate over variables
27  foreach (var decl in shaderClassType.Members.OfType<Variable>())
28  {
29  if (decl.Qualifiers.Contains(SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier.Extern)
30  || decl.Qualifiers.Contains(SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier.Const)
31  || decl.Qualifiers.Contains(ParadoxStorageQualifier.Stream))
32  continue;
33 
34  try
35  {
36  if (decl.Attributes.OfType<AttributeDeclaration>().Any(x => x.Name == "RenameLink"))
37  continue;
38 
39  ShaderKeyVariable variable = null;
40  var type = decl.Type.ResolveType();
41  bool isArray = type is ArrayType;
42  bool processInitialValue = false;
43  bool isColor = decl.Attributes.OfType<AttributeDeclaration>().Any(x => x.Name == "Color");
44 
45  if (isArray)
46  {
47  type = ((ArrayType)type).Type.ResolveType();
48  }
49 
50  if (type is ScalarType)
51  {
52  processInitialValue = true;
53  variable = new ShaderKeyVariable(decl.Name, ((ScalarType)type).Type.FullName,
55  }
56  else if (type is VectorType)
57  {
58  processInitialValue = true;
59  var typeName = "Vector" + ((VectorType)type).Dimension;
60  if (isColor)
61  {
62  if (((VectorType)type).Dimension == 3)
63  typeName = "Color3";
64  else if (((VectorType)type).Dimension == 4)
65  typeName = "Color4";
66  else
67  throw new NotSupportedException("Color attribute is only valid for float3/float4.");
68  }
69  variable = new ShaderKeyVariable(decl.Name, typeName,
71  }
72  else if (type is MatrixType)
73  {
74  processInitialValue = true;
75  variable = new ShaderKeyVariable(decl.Name, "Matrix", ShaderKeyVariableCategory.Value);
76  }
77  else if (type is TextureType || IsStringInList(type.Name, "Texture1D", "RWTexture1D", "Texture2D", "RWTexture2D", "Texture3D", "RWTexture3D"))
78  {
79  variable = new ShaderKeyVariable(decl.Name, "Texture", ShaderKeyVariableCategory.Resource);
80  }
81  else if (type is StateType && type.Name == "SamplerState")
82  {
83  variable = new ShaderKeyVariable(decl.Name, "SamplerState", ShaderKeyVariableCategory.Resource);
84  }
85  else if (type is GenericType<ObjectType> &&
86  IsStringInList(type.Name, "StructuredBuffer", "RWStructuredBuffer", "ConsumeStructuredBuffer",
87  "AppendStructuredBuffer"))
88  {
89  variable = new ShaderKeyVariable(decl.Name, "Buffer", ShaderKeyVariableCategory.Resource);
90  }
91 
92  if (isArray && variable != null && variable.Category == ShaderKeyVariableCategory.Value)
93  {
94  variable.Category = ShaderKeyVariableCategory.ArrayValue;
95  }
96 
97  if (variable == null)
98  {
99  throw new NotSupportedException();
100  }
101 
102  if (decl.InitialValue != null && processInitialValue)
103  {
104  variable.InitialValue = decl.InitialValue.ToString();
105 
106  // Add new operator for array
107  if (isArray && variable.InitialValue.Contains("{"))
108  variable.InitialValue = "new " + variable.Type + "[] " + variable.InitialValue;
109  }
110  else if (isArray && processInitialValue)
111  {
112  // Default array initializer
113  var dimensions = ((ArrayType)decl.Type.ResolveType()).Dimensions;
114  if (dimensions.Count != 1)
115  throw new NotSupportedException();
116  var expressionEvaluator = new ExpressionEvaluator();
117  var expressionResult = expressionEvaluator.Evaluate(dimensions[0]);
118  if (expressionResult.HasErrors)
119  throw new InvalidOperationException();
120  variable.InitialValue = "new " + variable.Type + "[" + expressionResult.Value + "]";
121  variable.Type += "[]";
122  }
123 
124  if (variable.InitialValue != null)
125  {
126  // Rename float2/3/4 to Vector2/3/4
127  if (variable.InitialValue.StartsWith("float2")
128  || variable.InitialValue.StartsWith("float3")
129  || variable.InitialValue.StartsWith("float4"))
130  variable.InitialValue = variable.InitialValue.Replace("float", "new Vector");
131 
132  if (isColor)
133  {
134  variable.InitialValue = variable.InitialValue.Replace("Vector3", "Color3");
135  variable.InitialValue = variable.InitialValue.Replace("Vector4", "Color4");
136  }
137  }
138 
139  var variableType = decl.Attributes.OfType<AttributeDeclaration>().Where(x => x.Name == "Type").Select(x => (string)x.Parameters[0].Value).FirstOrDefault();
140  if (variableType != null)
141  variable.Type = variableType;
142 
143  variable.Map = decl.Attributes.OfType<AttributeDeclaration>().Where(x => x.Name == "Map").Select(x => (string)x.Parameters[0].Value).FirstOrDefault();
144 
145  // First time initialization
146  if (shaderKeyClass == null)
147  shaderKeyClass = new ShaderKeyClass(shaderClassType.Name + "Keys");
148  shaderKeyClass.Variables.Add(variable);
149  }
150  catch (Exception)
151  {
152  Console.WriteLine("Could not process variable {0}.{1} of type {2}", shaderClassType.Name, decl.Name,
153  decl.Type);
154  }
155  }
156  return shaderKeyClass;
157  }
158 
159  private static bool IsStringInList(string value, params string[] list)
160  {
161  return list.Any(str => string.Compare(value, str, StringComparison.InvariantCultureIgnoreCase) == 0);
162  }
163  }
164 }
Base class for all vector types
Definition: VectorType.cs:10
static readonly SiliconStudio.Shaders.Ast.StorageQualifier Stream
Stream keyword (stream).
Identifier Name
Gets or sets the name of this declaration
Definition: IDeclaration.cs:16
Let the emitter choose the style.
A variable declaration.
Definition: Variable.cs:11
Base class for all generic types.
Definition: GenericType.cs:14
List< Node > Members
Gets or sets the members.
Definition: ClassType.cs:64
Identifier Name
Gets or sets the type name.
Definition: TypeBase.cs:77