Add new unit tests for SkSL.

These cover:
- Properly configured out-params
- Invalid/non-lvalue out-params, which currently cause an SkSL crash
- Interactions between the inliner and variable swizzles

Change-Id: I4874101236084f273e704d8717149b431d813883
Bug: skia:10753
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319036
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index 4bb4bcd..01926ac 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -95,6 +95,7 @@
   "$_tests/sksl/errors/InterfaceBlockScope.sksl",
   "$_tests/sksl/errors/InterfaceBlockStorageModifiers.sksl",
   "$_tests/sksl/errors/InvalidAssignment.sksl",
+  "$_tests/sksl/errors/InvalidOutParams.sksl",
   "$_tests/sksl/errors/InvalidUnary.sksl",
   "$_tests/sksl/errors/OpenArray.sksl",
   "$_tests/sksl/errors/ReturnDifferentType.sksl",
@@ -180,6 +181,7 @@
   "$_tests/sksl/glsl/NumberConversions.sksl",
   "$_tests/sksl/glsl/Offset.sksl",
   "$_tests/sksl/glsl/Operators.sksl",
+  "$_tests/sksl/glsl/OutParams.sksl",
   "$_tests/sksl/glsl/RectangleTexture.sksl",
   "$_tests/sksl/glsl/ResizeMatrix.sksl",
   "$_tests/sksl/glsl/SampleMask.sksl",
@@ -247,6 +249,7 @@
   "$_tests/sksl/inliner/SwitchWithCastCanBeInlined.sksl",
   "$_tests/sksl/inliner/SwitchWithReturnInsideCannotBeInlined.sksl",
   "$_tests/sksl/inliner/SwitchWithoutReturnInsideCanBeInlined.sksl",
+  "$_tests/sksl/inliner/SwizzleCanBeInlinedDirectly.sksl",
   "$_tests/sksl/inliner/TernaryResultsCannotBeInlined.sksl",
   "$_tests/sksl/inliner/TernaryTestCanBeInlined.sksl",
   "$_tests/sksl/inliner/WhileBodyMustBeInlinedIntoAScope.sksl",
diff --git a/tests/sksl/errors/InvalidOutParams.sksl b/tests/sksl/errors/InvalidOutParams.sksl
new file mode 100644
index 0000000..6194db8
--- /dev/null
+++ b/tests/sksl/errors/InvalidOutParams.sksl
@@ -0,0 +1,6 @@
+void inc1(out float x)  { x++; }
+void inc4(out float4 x) { x += half4(1); }
+
+void test_a() { inc1(0); }
+void test_b() { inc4(float4(0)); }
+void test_c() { inc1(sqrt(1)); }
diff --git a/tests/sksl/errors/golden/InvalidOutParams.glsl b/tests/sksl/errors/golden/InvalidOutParams.glsl
new file mode 100644
index 0000000..9d598bb
--- /dev/null
+++ b/tests/sksl/errors/golden/InvalidOutParams.glsl
@@ -0,0 +1,3 @@
+### Compilation failed:
+
+
diff --git a/tests/sksl/glsl/OutParams.sksl b/tests/sksl/glsl/OutParams.sksl
new file mode 100644
index 0000000..0fd599a
--- /dev/null
+++ b/tests/sksl/glsl/OutParams.sksl
@@ -0,0 +1,63 @@
+void out_half (out half  v) { v = 1; }
+void out_half2(out half2 v) { v = half2(2); }
+void out_half3(out half3 v) { v = half3(3); }
+void out_half4(out half4 v) { v = half4(4); }
+
+void out_half2x2(out half2x2 v) { v = half2x2(2); }
+void out_half3x3(out half3x3 v) { v = half3x3(3); }
+void out_half4x4(out half4x4 v) { v = half4x4(4); }
+
+void out_int (out int  v) { v = 1; }
+void out_int2(out int2 v) { v = int2(2); }
+void out_int3(out int3 v) { v = int3(3); }
+void out_int4(out int4 v) { v = int4(4); }
+
+void out_float (out float  v) { v = 1; }
+void out_float2(out float2 v) { v = float2(2); }
+void out_float3(out float3 v) { v = float3(3); }
+void out_float4(out float4 v) { v = float4(4); }
+
+void out_float2x2(out float2x2 v) { v = float2x2(2); }
+void out_float3x3(out float3x3 v) { v = float3x3(3); }
+void out_float4x4(out float4x4 v) { v = float4x4(4); }
+
+void out_bool (out bool  v) { v = true; }
+void out_bool2(out bool2 v) { v = bool2(false); }
+void out_bool3(out bool3 v) { v = bool3(true);  }
+void out_bool4(out bool4 v) { v = bool4(false); }
+
+void main() {
+    half     h;    out_half (h);
+    half2    h2;   out_half2(h2);
+    half3    h3;   out_half3(h3);
+    half4    h4;   out_half4(h4);
+    sk_FragColor = half4(h, h2.x, h3.x, h4.x);
+
+    half2x2  h2x2; out_half2x2(h2x2);
+    half3x3  h3x3; out_half3x3(h3x3);
+    half4x4  h4x4; out_half4x4(h4x4);
+    sk_FragColor = half4(h2x2[0][0], h3x3[0][0], h4x4[0][0], 1);
+
+    int      i;    out_int (i);
+    int2     i2;   out_int2(i2);
+    int3     i3;   out_int3(i3);
+    int4     i4;   out_int4(i4);
+    sk_FragColor = half4(i, i2.x, i3.x, i4.x);
+
+    float    f;    out_float (f);
+    float2   f2;   out_float2(f2);
+    float3   f3;   out_float3(f3);
+    float4   f4;   out_float4(f4);
+    sk_FragColor = half4(half(f), half(f2.x), half(f3.x), half(f4.x));
+
+    float2x2 f2x2; out_float2x2(f2x2);
+    float3x3 f3x3; out_float3x3(f3x3);
+    float4x4 f4x4; out_float4x4(f4x4);
+    sk_FragColor = half4(half(f2x2[0][0]), half(f3x3[0][0]), half(f4x4[0][0]), 1);
+
+    bool     b;    out_bool (b);
+    bool2    b2;   out_bool2(b2);
+    bool3    b3;   out_bool3(b3);
+    bool4    b4;   out_bool4(b4);
+    sk_FragColor = half4(half(b), half(b2.x), half(b3.x), half(b4.x));
+}
diff --git a/tests/sksl/glsl/golden/OutParams.glsl b/tests/sksl/glsl/golden/OutParams.glsl
new file mode 100644
index 0000000..475d9d7
--- /dev/null
+++ b/tests/sksl/glsl/golden/OutParams.glsl
@@ -0,0 +1,10 @@
+
+out vec4 sk_FragColor;
+void main() {
+    sk_FragColor = vec4(1.0, 2.0, 3.0, 4.0);
+    sk_FragColor = vec4(mat2(2.0)[0][0], mat3(3.0)[0][0], mat4(4.0)[0][0], 1.0);
+    sk_FragColor = vec4(1.0, 2.0, 3.0, 4.0);
+    sk_FragColor = vec4(1.0, 2.0, 3.0, 4.0);
+    sk_FragColor = vec4(mat2(2.0)[0][0], mat3(3.0)[0][0], mat4(4.0)[0][0], 1.0);
+    sk_FragColor = vec4(1.0, bvec2(false).x ? 1.0 : 0.0, bvec3(true).x ? 1.0 : 0.0, bvec4(false).x ? 1.0 : 0.0);
+}
diff --git a/tests/sksl/inliner/SwizzleCanBeInlinedDirectly.sksl b/tests/sksl/inliner/SwizzleCanBeInlinedDirectly.sksl
new file mode 100644
index 0000000..468c1cb
--- /dev/null
+++ b/tests/sksl/inliner/SwizzleCanBeInlinedDirectly.sksl
@@ -0,0 +1,19 @@
+uniform half4 inColor;
+
+half4 flip(half4 v) {
+    return v.wzyx;
+}
+
+void mutating_flip(out half4 v) {
+    v = v.wzyx;
+}
+
+void main() {
+    half4 color = inColor;
+
+    sk_FragColor = color.xyzy.wzyx;
+    sk_FragColor = flip(color.xyzy);
+
+    mutating_flip(color);
+    sk_FragColor = color;
+}
diff --git a/tests/sksl/inliner/golden/SwizzleCanBeInlinedDirectly.glsl b/tests/sksl/inliner/golden/SwizzleCanBeInlinedDirectly.glsl
new file mode 100644
index 0000000..2658c08
--- /dev/null
+++ b/tests/sksl/inliner/golden/SwizzleCanBeInlinedDirectly.glsl
@@ -0,0 +1,21 @@
+
+out vec4 sk_FragColor;
+uniform vec4 inColor;
+void main() {
+    vec4 color = inColor;
+    sk_FragColor = color.yzyx;
+    vec4 _0_flip;
+    vec4 _1_v = color.xyzy;
+    {
+        _0_flip = _1_v.wzyx;
+    }
+
+    sk_FragColor = _0_flip;
+
+    {
+        color = color.wzyx;
+    }
+
+
+    sk_FragColor = color;
+}