123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657 |
- using System;
- using System.Globalization;
- using NUnit.Framework;
- using UnityEngine;
- using UnityEditor.Graphing;
- using UnityEditor.ShaderGraph;
- using UnityEditor.ShaderGraph.Internal;
-
- namespace UnityEditor.ShaderGraph.UnitTests
- {
- [TestFixture]
- class ShaderGeneratorTests
- {
- [OneTimeSetUp]
- public void RunBeforeAnyTests()
- {
- Debug.unityLogger.logHandler = new ConsoleLogHandler();
- }
-
- class TestNode : AbstractMaterialNode
- {
- public const int V1Out = 0;
- public const int V2Out = 1;
- public const int V3Out = 2;
- public const int V4Out = 3;
-
- public TestNode()
- {
- AddSlot(new Vector1MaterialSlot(V1Out, "V1Out", "V1Out", SlotType.Output, 0));
- AddSlot(new Vector2MaterialSlot(V2Out, "V2Out", "V2Out", SlotType.Output, Vector4.zero));
- AddSlot(new Vector3MaterialSlot(V3Out, "V3Out", "V3Out", SlotType.Output, Vector4.zero));
- AddSlot(new Vector4MaterialSlot(V4Out, "V4Out", "V4Out", SlotType.Output, Vector4.zero));
- }
- }
-
- [Test]
- public void AdaptNodeOutput1To1Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector1);
- Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V1Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput1To2Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector2);
- Assert.AreEqual(string.Format("({0}.xx)", node.GetVariableNameForSlot(TestNode.V1Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput1To3Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector3);
- Assert.AreEqual(string.Format("({0}.xxx)", node.GetVariableNameForSlot(TestNode.V1Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput1To4Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V1Out, ConcreteSlotValueType.Vector4);
- Assert.AreEqual(string.Format("({0}.xxxx)", node.GetVariableNameForSlot(TestNode.V1Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput2To1Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector1);
- Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V2Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput2To2Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector2);
- Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V2Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput2To3Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector3);
- Assert.AreEqual(string.Format("($precision3({0}, 0.0))", node.GetVariableNameForSlot(TestNode.V2Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput2To4Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V2Out, ConcreteSlotValueType.Vector4);
- Assert.AreEqual(string.Format("($precision4({0}, 0.0, 1.0))", node.GetVariableNameForSlot(TestNode.V2Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput3To1Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector1);
- Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V3Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput3To2Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector2);
- Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(TestNode.V3Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput3To3Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector3);
- Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V3Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput3To4Fails()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V3Out, ConcreteSlotValueType.Vector4);
- Assert.AreEqual(string.Format("($precision4({0}, 1.0))", node.GetVariableNameForSlot(TestNode.V3Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput4To1Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector1);
- Assert.AreEqual(string.Format("({0}).x", node.GetVariableNameForSlot(TestNode.V4Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput4To2Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector2);
- Assert.AreEqual(string.Format("({0}.xy)", node.GetVariableNameForSlot(TestNode.V4Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput4To3Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector3);
- Assert.AreEqual(string.Format("({0}.xyz)", node.GetVariableNameForSlot(TestNode.V4Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput4To4Works()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutput(node, TestNode.V4Out, ConcreteSlotValueType.Vector4);
- Assert.AreEqual(string.Format("{0}", node.GetVariableNameForSlot(TestNode.V4Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput1To4PreviewWorks()
- {
- var node = new TestNode();
- var result = GenerationUtils.AdaptNodeOutputForPreview(node, TestNode.V1Out);
- Assert.AreEqual(string.Format("half4({0}, {0}, {0}, 1.0)", node.GetVariableNameForSlot(TestNode.V1Out)), result);
- }
-
- [Test]
- public void AdaptNodeOutput2To4PreviewWorks()
- {
- var node = new TestNode();
- var expected = string.Format("half4({0}.x, {0}.y, 0.0, 1.0)", node.GetVariableNameForSlot(TestNode.V2Out));
- var result = GenerationUtils.AdaptNodeOutputForPreview(node, TestNode.V2Out);
- Assert.AreEqual(expected, result);
- }
-
- [Test]
- public void AdaptNodeOutput3To4PreviewWorks()
- {
- var node = new TestNode();
- var expected = string.Format("half4({0}.x, {0}.y, {0}.z, 1.0)", node.GetVariableNameForSlot(TestNode.V3Out));
- var result = GenerationUtils.AdaptNodeOutputForPreview(node, TestNode.V3Out);
- Assert.AreEqual(expected, result);
- }
-
- [Test]
- public void AdaptNodeOutput4To4PreviewWorks()
- {
- var node = new TestNode();
- var expected = string.Format("half4({0}.x, {0}.y, {0}.z, 1.0)", node.GetVariableNameForSlot(TestNode.V4Out));
- var result = GenerationUtils.AdaptNodeOutputForPreview(node, TestNode.V4Out);
- Assert.AreEqual(expected, result);
- }
-
- public struct PackingTestCase
- {
- internal string name;
- internal StructDescriptor inputStruct;
- internal StructDescriptor expectedOutputStruct;
- internal string expectedInterpolatorFunction;
- public override string ToString()
- {
- return name;
- }
- }
-
- public static readonly PackingTestCase[] s_PackingTestCase = new[]
- {
- new PackingTestCase()
- {
- name = "Simple_With_Semantic",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "position", define: string.Empty, type: ShaderValueType.Float4, semantic: "SV_POSITION", interpolation: "SV_POSITION_QUALIFIERS"),
- new FieldDescriptor(tag: "Original", name: "normalWS", define: string.Empty, type: ShaderValueType.Float3, semantic: "NORMAL_WS", interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloatA", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- }
- },
-
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "position", define: string.Empty, type: ShaderValueType.Float4, semantic: "SV_POSITION", interpolation: "SV_POSITION_QUALIFIERS"),
- new FieldDescriptor(tag: "Original", name: "normalWS", define: string.Empty, type: ShaderValueType.Float3, semantic: "NORMAL_WS", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "myFloatA", define: string.Empty, type: "float1", semantic: "INTERP0", interpolation: string.Empty),
- }
- },
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.position = input.position;
- output.normalWS = input.normalWS;
- output.myFloatA.x = input.myFloatA;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.position = input.position;
- output.normalWS = input.normalWS;
- output.myFloatA = input.myFloatA.x;
- return output;
- }"
- },
-
- new PackingTestCase()
- {
- name = "Equivalent_Packing_F3F3F1F1_A",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "myVector3_A", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myVector3_B", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_A", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_B", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- }
- },
-
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new []
- {
- new FieldDescriptor(tag: "PackedInput", name: "packed_myVector3_A_myFloat_A", define: string.Empty, type: "float4", semantic: "INTERP0", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myVector3_B_myFloat_B", define: string.Empty, type: "float4", semantic: "INTERP1", interpolation: string.Empty),
- }
- },
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.packed_myVector3_A_myFloat_A.xyz = input.myVector3_A;
- output.packed_myVector3_A_myFloat_A.w = input.myFloat_A;
- output.packed_myVector3_B_myFloat_B.xyz = input.myVector3_B;
- output.packed_myVector3_B_myFloat_B.w = input.myFloat_B;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.myVector3_A = input.packed_myVector3_A_myFloat_A.xyz;
- output.myFloat_A = input.packed_myVector3_A_myFloat_A.w;
- output.myVector3_B = input.packed_myVector3_B_myFloat_B.xyz;
- output.myFloat_B = input.packed_myVector3_B_myFloat_B.w;
- return output;
- }"
- },
-
- new PackingTestCase()
- {
- name = "Equivalent_Packing_F3F3F1F1_B",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- //This test insure the order of input packing doesn't fail the following packing
- new FieldDescriptor(tag: "Original", name: "myFloat_A", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_B", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myVector3_A", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myVector3_B", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- }
- },
-
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new []
- {
- new FieldDescriptor(tag: "PackedInput", name: "packed_myVector3_A_myFloat_A", define: string.Empty, type: "float4", semantic: "INTERP0", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myVector3_B_myFloat_B", define: string.Empty, type: "float4", semantic: "INTERP1", interpolation: string.Empty),
- }
- },
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.packed_myVector3_A_myFloat_A.xyz = input.myVector3_A;
- output.packed_myVector3_A_myFloat_A.w = input.myFloat_A;
- output.packed_myVector3_B_myFloat_B.xyz = input.myVector3_B;
- output.packed_myVector3_B_myFloat_B.w = input.myFloat_B;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.myVector3_A = input.packed_myVector3_A_myFloat_A.xyz;
- output.myFloat_A = input.packed_myVector3_A_myFloat_A.w;
- output.myVector3_B = input.packed_myVector3_B_myFloat_B.xyz;
- output.myFloat_B = input.packed_myVector3_B_myFloat_B.w;
- return output;
- }"
- },
-
- new PackingTestCase()
- {
- name = "Packing_F3F3F2",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "myFloat_A", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_B", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myVector2", define: string.Empty, type: ShaderValueType.Float2, semantic: string.Empty, interpolation: string.Empty),
- }
- },
-
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new []
- {
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloat_A_myVector2x", define: string.Empty, type: "float4", semantic: "INTERP0", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloat_B_myVector2y", define: string.Empty, type: "float4", semantic: "INTERP1", interpolation: string.Empty),
- }
- },
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.packed_myFloat_A_myVector2x.xyz = input.myFloat_A;
- output.packed_myFloat_A_myVector2x.w = input.myVector2.x;
- output.packed_myFloat_B_myVector2y.xyz = input.myFloat_B;
- output.packed_myFloat_B_myVector2y.w = input.myVector2.y;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.myFloat_A = input.packed_myFloat_A_myVector2x.xyz;
- output.myVector2.x = input.packed_myFloat_A_myVector2x.w;
- output.myFloat_B = input.packed_myFloat_B_myVector2y.xyz;
- output.myVector2.y = input.packed_myFloat_B_myVector2y.w;
- return output;
- }
- "
- },
-
- new PackingTestCase()
- {
- name = "Packing_F3F3F3F3",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "myFloat3_A", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat3_B", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat3_C", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat3_D", define: string.Empty, type: ShaderValueType.Float3, semantic: string.Empty, interpolation: string.Empty),
- }
- },
-
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new []
- {
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloat3_A_myFloat3_Dx", define: string.Empty, type: "float4", semantic: "INTERP0", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloat3_B_myFloat3_Dy", define: string.Empty, type: "float4", semantic: "INTERP1", interpolation: string.Empty),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloat3_C_myFloat3_Dz", define: string.Empty, type: "float4", semantic: "INTERP2", interpolation: string.Empty),
- }
- },
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.packed_myFloat3_A_myFloat3_Dx.xyz = input.myFloat3_A;
- output.packed_myFloat3_A_myFloat3_Dx.w = input.myFloat3_D.x;
- output.packed_myFloat3_B_myFloat3_Dy.xyz = input.myFloat3_B;
- output.packed_myFloat3_B_myFloat3_Dy.w = input.myFloat3_D.y;
- output.packed_myFloat3_C_myFloat3_Dz.xyz = input.myFloat3_C;
- output.packed_myFloat3_C_myFloat3_Dz.w = input.myFloat3_D.z;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.myFloat3_A = input.packed_myFloat3_A_myFloat3_Dx.xyz;
- output.myFloat3_D.x = input.packed_myFloat3_A_myFloat3_Dx.w;
- output.myFloat3_B = input.packed_myFloat3_B_myFloat3_Dy.xyz;
- output.myFloat3_D.y = input.packed_myFloat3_B_myFloat3_Dy.w;
- output.myFloat3_C = input.packed_myFloat3_C_myFloat3_Dz.xyz;
- output.myFloat3_D.z = input.packed_myFloat3_C_myFloat3_Dz.w;
- return output;
- }
- "
- },
-
- new PackingTestCase()
- {
- name = "Typical_Use_Case",
- inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new []
- {
- new FieldDescriptor(tag: "Original", name: "position", define: string.Empty, type: ShaderValueType.Float4, semantic: "SV_POSITION", interpolation: "SV_POSITION_QUALIFIERS"),
- new FieldDescriptor(tag: "Original", name: "myIntA", define: string.Empty, type: ShaderValueType.Integer, semantic: string.Empty, interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "Original", name: "myIntB", define: string.Empty, type: ShaderValueType.Integer, semantic: string.Empty, interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "Original", name: "myFloatA", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "Original", name: "myFloatB", define: string.Empty, type: ShaderValueType.Float2, semantic: string.Empty, interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "Original", name: "myInterFloatA", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myInterFloatB", define: string.Empty, type: ShaderValueType.Float2, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "instanceID", define: string.Empty, type: ShaderValueType.Uint, semantic: "CUSTOM_INSTANCE_ID", preprocessor: "UNITY_ANY_INSTANCING_ENABLED")
- }
- },
- expectedOutputStruct = new StructDescriptor()
- {
- name = "PackedInput",
- packFields = true,
- fields = new[]
- {
- new FieldDescriptor(tag: "Original", name: "position", define: string.Empty, type: ShaderValueType.Float4, semantic: "SV_POSITION", interpolation: "SV_POSITION_QUALIFIERS"),
- new FieldDescriptor(tag: "PackedInput", name: "myIntA", define: string.Empty, type: ShaderValueType.Integer, semantic: "INTERP0", interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "PackedInput", name: "myIntB", define: string.Empty, type: ShaderValueType.Integer, semantic: "INTERP1", interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myFloatB_myFloatA", define: string.Empty, type: "float3", semantic: "INTERP2", interpolation: "nointerpolation"),
- new FieldDescriptor(tag: "PackedInput", name: "packed_myInterFloatB_myInterFloatA", define: string.Empty, type: "float3", semantic: "INTERP3", interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "instanceID", define: string.Empty, type: ShaderValueType.Uint, semantic: "CUSTOM_INSTANCE_ID", preprocessor: "UNITY_ANY_INSTANCING_ENABLED")
- }
- },
-
- expectedInterpolatorFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.position = input.position;
- output.myIntA = input.myIntA;
- output.myIntB = input.myIntB;
- output.packed_myFloatB_myFloatA.xy = input.myFloatB;
- output.packed_myFloatB_myFloatA.z = input.myFloatA;
- output.packed_myInterFloatB_myInterFloatA.xy = input.myInterFloatB;
- output.packed_myInterFloatB_myInterFloatA.z = input.myInterFloatA;
- #if UNITY_ANY_INSTANCING_ENABLED
- output.instanceID = input.instanceID;
- #endif
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.position = input.position;
- output.myIntA = input.myIntA;
- output.myIntB = input.myIntB;
- output.myFloatB = input.packed_myFloatB_myFloatA.xy;
- output.myFloatA = input.packed_myFloatB_myFloatA.z;
- output.myInterFloatB = input.packed_myInterFloatB_myInterFloatA.xy;
- output.myInterFloatA = input.packed_myInterFloatB_myInterFloatA.z;
- #if UNITY_ANY_INSTANCING_ENABLED
- output.instanceID = input.instanceID;
- #endif
- return output;
- }"
- }
- };
-
- [Test]
- public void GenerationUtils_GeneratePackedStruct([ValueSource(nameof(s_PackingTestCase))] PackingTestCase testCase)
- {
- var activeFields = new ActiveFields();
- foreach (var field in testCase.inputStruct.fields)
- activeFields.all.AddAll(field);
-
- GenerationUtils.GeneratePackedStruct(testCase.inputStruct, activeFields, out var packedStruct);
-
- var expected = testCase.expectedOutputStruct;
- Assert.AreEqual(expected.name, packedStruct.name);
- Assert.AreEqual(expected.packFields, packedStruct.packFields);
- Assert.AreEqual(expected.fields.Length, packedStruct.fields.Length);
- for (int i = 0; i < expected.fields.Length; i++)
- {
- var currentField = packedStruct.fields[i];
- var expectedField = expected.fields[i];
- Assert.AreEqual(expectedField.tag, currentField.tag);
- Assert.AreEqual(expectedField.name, currentField.name);
- Assert.AreEqual(expectedField.define, currentField.define);
- Assert.AreEqual(expectedField.interpolation, currentField.interpolation);
- Assert.AreEqual(expectedField.type, currentField.type);
- Assert.AreEqual(expectedField.vectorCount, currentField.vectorCount);
- Assert.AreEqual(expectedField.semantic, currentField.semantic);
- Assert.AreEqual(expectedField.preprocessor, currentField.preprocessor);
- Assert.AreEqual(expectedField.subscriptOptions, currentField.subscriptOptions);
- }
- }
-
- [Test]
- public void GenerationUtils_GenerateInterpolatorFunctions([ValueSource(nameof(s_PackingTestCase))] PackingTestCase packingTestCase)
- {
- var activeFields = new ActiveFields();
- foreach (var field in packingTestCase.inputStruct.fields)
- activeFields.all.AddAll(field);
-
- GenerationUtils.GenerateInterpolatorFunctions(packingTestCase.inputStruct, activeFields.baseInstance, true, out var shaderFunction);
-
- var result = shaderFunction.ToString();
- int length = Math.Max(packingTestCase.expectedInterpolatorFunction.Length, result.Length);
- var compare = String.Compare(packingTestCase.expectedInterpolatorFunction, 0, result, 0, length, CultureInfo.InvariantCulture, CompareOptions.IgnoreSymbols);
- Assert.AreEqual(0, compare, "Unexpected generated function:\n" + result);
-
- }
-
- [Test]
- public void GenerationUtils_ActivationFields()
- {
- var inputStruct = new StructDescriptor()
- {
- name = "Input",
- packFields = false,
- fields = new[]
- {
- //This test insure the order of input packing doesn't fail the following packing
- new FieldDescriptor(tag: "Original", name: "myFloat_Cond_0", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_Cond_1", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_Cond_2", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- new FieldDescriptor(tag: "Original", name: "myFloat_Cond_ALL", define: string.Empty, type: ShaderValueType.Float, semantic: string.Empty, interpolation: string.Empty),
- }
- };
-
- var activeFields = new ActiveFields();
- foreach (var field in inputStruct.fields)
- {
- var index = field.name.EndsWith("0") ? 0 : field.name.EndsWith("1") ? 1 : field.name.EndsWith("2") ? 2 : -1;
- if (index != -1)
- {
- activeFields[index].Add(field);
- }
- else
- {
- activeFields.all.AddAll(field);
- }
- }
-
- GenerationUtils.GenerateInterpolatorFunctions(inputStruct, activeFields.baseInstance, true, out var shaderFunctionBuilder);
- GenerationUtils.GeneratePackedStruct(inputStruct, activeFields, out var packedStruct);
- GenerationUtils.GenerateShaderStruct(packedStruct, activeFields, true, out var structDeclarationBuilder);
-
- var expectedShaderFunction = @"
- PackedInput PackInput (Input input)
- {
- PackedInput output;
- ZERO_INITIALIZE(PackedInput, output);
- output.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.x = input.myFloat_Cond_0;
- output.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.y = input.myFloat_Cond_1;
- output.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.z = input.myFloat_Cond_2;
- output.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.w = input.myFloat_Cond_ALL;
- return output;
- }
-
- Input UnpackInput (PackedInput input)
- {
- Input output;
- output.myFloat_Cond_0 = input.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.x;
- output.myFloat_Cond_1 = input.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.y;
- output.myFloat_Cond_2 = input.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.z;
- output.myFloat_Cond_ALL = input.packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL.w;
- return output;
- }";
-
- var expectedStructDeclaration = @"
- struct PackedInput
- {
- #if defined(KEYWORD_PERMUTATION_0) || defined(KEYWORD_PERMUTATION_1) || defined(KEYWORD_PERMUTATION_2)
- float4 packed_myFloat_Cond_0_myFloat_Cond_1_myFloat_Cond_2_myFloat_Cond_ALL : INTERP0;
- #endif
- };";
- {
- var shaderFunction = shaderFunctionBuilder.ToString();
- var length = Math.Max(expectedShaderFunction.Length, shaderFunction.Length);
- var compare = String.Compare(expectedShaderFunction, 0, shaderFunction, 0, length, CultureInfo.InvariantCulture, CompareOptions.IgnoreSymbols);
- Assert.AreEqual(0, compare, "Unexpected generated function:\n" + shaderFunction);
- }
-
- {
- var structDeclaration = structDeclarationBuilder.ToString();
- var length = Math.Max(expectedStructDeclaration.Length, structDeclaration.Length);
- var compare = String.Compare(expectedStructDeclaration, 0, expectedStructDeclaration, 0, length, CultureInfo.InvariantCulture, CompareOptions.IgnoreSymbols);
- Assert.AreEqual(0, compare, "Unexpected generated function:\n" + structDeclaration);
- }
- }
- }
- }
|