Procházet zdrojové kódy

Add mappings for all Vector constructors.

Eric Mellino před 8 roky
rodič
revize
3fb8c8ef1a

+ 1 - 0
src/ShaderGen.Tests/ShaderGeneratorTests.cs

@@ -24,6 +24,7 @@ namespace ShaderGen.Tests
             yield return new object[] { "TestShaders.CustomMethodCalls.VS", null };
             yield return new object[] { "TestShaders.VeldridShaders.ShadowDepth.VS", "TestShaders.VeldridShaders.ShadowDepth.FS" };
             yield return new object[] { "TestShaders.ShaderBuiltinsTestShader.VS", null };
+            yield return new object[] { "TestShaders.VectorConstructors.VS", null };
         }
 
         [Theory]

+ 29 - 0
src/ShaderGen.Tests/TestAssets/VectorConstructors.cs

@@ -0,0 +1,29 @@
+using ShaderGen;
+using System.Numerics;
+
+namespace TestShaders
+{
+    public class VectorConstructors
+    {
+        [VertexShader]
+        Position4 VS(Position4 input)
+        {
+            Vector2 v2 = new Vector2();
+            v2 = new Vector2(1);
+            v2 = new Vector2(1, 2);
+
+            Vector3 v3 = new Vector3();
+            v3 = new Vector3(1);
+            v3 = new Vector3(v2, 3);
+            v3 = new Vector3(1, 2, 3);
+
+            Vector4 v4 = new Vector4();
+            v4 = new Vector4(1);
+            v4 = new Vector4(v3, 4);
+            v4 = new Vector4(v2, 3, 4);
+            v4 = new Vector4(1, 2, 3, 4);
+
+            return input;
+        }
+    }
+}

+ 57 - 0
src/ShaderGen/Glsl330KnownFunctions.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Text;
 
 namespace ShaderGen
 {
@@ -27,15 +29,32 @@ namespace ShaderGen
             };
             ret.Add("ShaderGen.ShaderBuiltins", new DictionaryTypeInvocationTranslator(builtinMappings));
 
+            Dictionary<string, InvocationTranslator> v2Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector2", new DictionaryTypeInvocationTranslator(v2Mappings));
+
             Dictionary<string, InvocationTranslator> v3Mappings = new Dictionary<string, InvocationTranslator>()
             {
                 { "Normalize", SimpleNameTranslator("normalize") },
                 { "Dot", SimpleNameTranslator("dot") },
                 { "Distance", SimpleNameTranslator("distance") },
                 { "Reflect", SimpleNameTranslator("reflect") },
+                { "ctor", VectorCtor },
             };
             ret.Add("System.Numerics.Vector3", new DictionaryTypeInvocationTranslator(v3Mappings));
 
+            Dictionary<string, InvocationTranslator> v4Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector4", new DictionaryTypeInvocationTranslator(v4Mappings));
+
             ret.Add("ShaderGen.ShaderSwizzle", new SwizzleTranslator());
 
             return ret;
@@ -94,5 +113,43 @@ namespace ShaderGen
             string target = parameters[0].Identifier;
             return $"vec2(({target}.x / {target}.w) / 2 + 0.5, ({target}.y / {target}.w) / 2 + 0.5)";
         }
+
+        private static string VectorCtor(string typeName, string methodName, InvocationParameterInfo[] parameters)
+        {
+            string glslName = null;
+            int elementCount = 0;
+            if (typeName == "System.Numerics.Vector2") { glslName = "vec2"; elementCount = 2; }
+            else if (typeName == "System.Numerics.Vector3") { glslName = "vec3"; elementCount = 3; }
+            else if (typeName == "System.Numerics.Vector4") { glslName = "vec4"; elementCount = 4; }
+            else { throw new ShaderGenerationException("VectorCtor translator was called on an invalid type: " + typeName); }
+
+            string paramList;
+            if (parameters.Length == 0)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat("0", elementCount));
+            }
+            else if (parameters.Length == 1)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat(parameters[0].Identifier, elementCount));
+            }
+            else
+            {
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < parameters.Length; i++)
+                {
+                    InvocationParameterInfo ipi = parameters[i];
+                    sb.Append(ipi.Identifier);
+
+                    if (i != parameters.Length - 1)
+                    {
+                        sb.Append(", ");
+                    }
+                }
+
+                paramList = sb.ToString();
+            }
+
+            return $"{glslName}({paramList})";
+        }
     }
 }

+ 57 - 0
src/ShaderGen/Glsl450KnownFunctions.cs

@@ -1,5 +1,7 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Text;
 
 namespace ShaderGen
 {
@@ -27,15 +29,32 @@ namespace ShaderGen
             };
             ret.Add("ShaderGen.ShaderBuiltins", new DictionaryTypeInvocationTranslator(builtinMappings));
 
+            Dictionary<string, InvocationTranslator> v2Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector2", new DictionaryTypeInvocationTranslator(v2Mappings));
+
             Dictionary<string, InvocationTranslator> v3Mappings = new Dictionary<string, InvocationTranslator>()
             {
                 { "Normalize", SimpleNameTranslator("normalize") },
                 { "Dot", SimpleNameTranslator("dot") },
                 { "Distance", SimpleNameTranslator("distance") },
                 { "Reflect", SimpleNameTranslator("reflect") },
+                { "ctor", VectorCtor },
             };
             ret.Add("System.Numerics.Vector3", new DictionaryTypeInvocationTranslator(v3Mappings));
 
+            Dictionary<string, InvocationTranslator> v4Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector4", new DictionaryTypeInvocationTranslator(v4Mappings));
+
             ret.Add("ShaderGen.ShaderSwizzle", new SwizzleTranslator());
 
             return ret;
@@ -105,5 +124,43 @@ namespace ShaderGen
             string target = parameters[0].Identifier;
             return $"vec2(({target}.x / {target}.w) / 2 + 0.5, ({target}.y / {target}.w) / -2 + 0.5)";
         }
+
+        private static string VectorCtor(string typeName, string methodName, InvocationParameterInfo[] parameters)
+        {
+            string glslName = null;
+            int elementCount = 0;
+            if (typeName == "System.Numerics.Vector2") { glslName = "vec2"; elementCount = 2; }
+            else if (typeName == "System.Numerics.Vector3") { glslName = "vec3"; elementCount = 3; }
+            else if (typeName == "System.Numerics.Vector4") { glslName = "vec4"; elementCount = 4; }
+            else { throw new ShaderGenerationException("VectorCtor translator was called on an invalid type: " + typeName); }
+
+            string paramList;
+            if (parameters.Length == 0)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat("0", elementCount));
+            }
+            else if (parameters.Length == 1)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat(parameters[0].Identifier, elementCount));
+            }
+            else
+            {
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < parameters.Length; i++)
+                {
+                    InvocationParameterInfo ipi = parameters[i];
+                    sb.Append(ipi.Identifier);
+
+                    if (i != parameters.Length - 1)
+                    {
+                        sb.Append(", ");
+                    }
+                }
+
+                paramList = sb.ToString();
+            }
+
+            return $"{glslName}({paramList})";
+        }
     }
 }

+ 59 - 0
src/ShaderGen/HlslKnownFunctions.cs

@@ -1,5 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
 
 namespace ShaderGen
 {
@@ -27,15 +30,33 @@ namespace ShaderGen
             };
             ret.Add("ShaderGen.ShaderBuiltins", new DictionaryTypeInvocationTranslator(builtinMappings));
 
+            Dictionary<string, InvocationTranslator> v2Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector2", new DictionaryTypeInvocationTranslator(v2Mappings));
+
             Dictionary<string, InvocationTranslator> v3Mappings = new Dictionary<string, InvocationTranslator>()
             {
                 { "Normalize", SimpleNameTranslator("normalize") },
                 { "Dot", SimpleNameTranslator("dot") },
                 { "Distance", SimpleNameTranslator("distance") },
                 { "Reflect", SimpleNameTranslator("reflect") },
+                { "ctor", VectorCtor },
             };
             ret.Add("System.Numerics.Vector3", new DictionaryTypeInvocationTranslator(v3Mappings));
 
+            Dictionary<string, InvocationTranslator> v4Mappings = new Dictionary<string, InvocationTranslator>()
+            {
+                { "Normalize", SimpleNameTranslator("normalize") },
+                { "Distance", SimpleNameTranslator("distance") },
+                { "ctor", VectorCtor },
+            };
+            ret.Add("System.Numerics.Vector4", new DictionaryTypeInvocationTranslator(v4Mappings));
+
+
             ret.Add("ShaderGen.ShaderSwizzle", new SwizzleTranslator());
 
             return ret;
@@ -77,6 +98,44 @@ namespace ShaderGen
             string target = parameters[0].Identifier;
             return $"float2(({target}.x / {target}.w) / 2 + 0.5, ({target}.y / {target}.w) / -2 + 0.5)";
         }
+
+        private static string VectorCtor(string typeName, string methodName, InvocationParameterInfo[] parameters)
+        {
+            string hlslName = null;
+            int elementCount = 0;
+            if (typeName == "System.Numerics.Vector2") { hlslName = "float2"; elementCount = 2; }
+            else if (typeName == "System.Numerics.Vector3") { hlslName = "float3"; elementCount = 3; }
+            else if (typeName == "System.Numerics.Vector4") { hlslName = "float4"; elementCount = 4; }
+            else { throw new ShaderGenerationException("VectorCtor translator was called on an invalid type: " + typeName); }
+
+            string paramList;
+            if (parameters.Length == 0)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat("0", elementCount));
+            }
+            else if (parameters.Length == 1)
+            {
+                paramList = string.Join(", ", Enumerable.Repeat(parameters[0].Identifier, elementCount));
+            }
+            else
+            {
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < parameters.Length; i++)
+                {
+                    InvocationParameterInfo ipi = parameters[i];
+                    sb.Append(ipi.Identifier);
+
+                    if (i != parameters.Length - 1)
+                    {
+                        sb.Append(", ");
+                    }
+                }
+
+                paramList = sb.ToString();
+            }
+
+            return $"{hlslName}({paramList})";
+        }
     }
 
     public delegate string InvocationTranslator(string typeName, string methodName, InvocationParameterInfo[] parameters);

+ 3 - 8
src/ShaderGen/ShaderMethodVisitor.cs

@@ -216,14 +216,9 @@ namespace ShaderGen
         {
             SymbolInfo symbolInfo = GetModel(node).GetSymbolInfo(node.Type);
             string fullName = Utilities.GetFullName(symbolInfo);
-
-            if (!Utilities.IsBasicNumericType(fullName))
-            {
-                throw new ShaderGenerationException(
-                    "Constructors can only be called on basic numeric types.");
-            }
-
-            return _backend.CSharpToShaderType(fullName) + "(" + Visit(node.ArgumentList) + ")";
+             
+            InvocationParameterInfo[] parameters = GetParameterInfos(node.ArgumentList);
+            return _backend.FormatInvocation(_setName, fullName, "ctor", parameters);
         }
 
         public override string VisitIdentifierName(IdentifierNameSyntax node)