SkSL: Test/implement "geometric" intrinsics

Bug: skia:10913
Change-Id: Ie82354b05db141c8ab90b1a615ddfada4f71a98b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335049
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/gm/runtimeintrinsics.cpp b/gm/runtimeintrinsics.cpp
index e4bd819..d7b246c 100644
--- a/gm/runtimeintrinsics.cpp
+++ b/gm/runtimeintrinsics.cpp
@@ -29,7 +29,8 @@
   produce a single float. It can reference:
 
     'x'  : float  in [xMin, xMax]
-    'p'  : float2 in [xMin, xMax] (helpful for intrinsics with a mix of scalar/vector params)
+    'p'  : float2 in [xMin, xMax]  Lerps from (xMax, xMin) to (xMin, xMax)
+                                   (helpful for intrinsics with a mix of scalar/vector params)
     'v1' : float2(1)
     'v2' : float2(2)
 */
@@ -40,7 +41,7 @@
             "half4 main(float2 p) {"
             "    float2 v1 = float2(1);"
             "    float2 v2 = float2(2);"
-            "    p = p * xScale + xBias;"
+            "    p = float2(p.x, 1 - p.x) * xScale + xBias;"
             "    float x = p.x;"
             "    float y = %s  * yScale + yBias;"
             "    return y.xxx1;"
@@ -233,3 +234,38 @@
     plot(canvas, "smoothstep(1, 2, p).x",   0.5f, 2.5f, -0.5f, 1.5f, "smooth(mixed)" ); col(canvas);
     plot(canvas, "smoothstep(v1, v2, p).x", 0.5f, 2.5f, -0.5f, 1.5f, "smooth(vector)"); row(canvas);
 }
+
+// The OpenGL ES Shading Language, Version 1.00, Section 8.4
+DEF_SIMPLE_GM_BG(runtime_intrinsics_geometric,
+                 canvas,
+                 columns_to_width(4),
+                 rows_to_height(5),
+                 SK_ColorWHITE) {
+    canvas->translate(kPadding, kPadding);
+    canvas->save();
+
+    plot(canvas, "length(x)",  -1.0f, 1.0f, -0.5f, 1.5f); col(canvas);
+    plot(canvas, "length(p)",   0.0f, 1.0f,  0.5f, 1.5f); col(canvas);
+
+    plot(canvas, "distance(x, 0)",  -1.0f, 1.0f, -0.5f, 1.5f); col(canvas);
+    plot(canvas, "distance(p, v1)",  0.0f, 1.0f,  0.5f, 1.5f); row(canvas);
+
+    plot(canvas, "dot(x, 2)",    -1.0f, 1.0f, -2.5f, 2.5f); col(canvas);
+    plot(canvas, "dot(p, p.y1)", -1.0f, 1.0f, -2.5f, 0.5f); row(canvas);
+
+    plot(canvas, "cross(p.xy1, p.y1x).x", 0.0f, 1.0f, -1.0f, 1.0f); col(canvas);
+    plot(canvas, "cross(p.xy1, p.y1x).y", 0.0f, 1.0f, -1.0f, 1.0f); col(canvas);
+    plot(canvas, "cross(p.xy1, p.y1x).z", 0.0f, 1.0f, -1.0f, 1.0f); row(canvas);
+
+    plot(canvas, "normalize(x)",   -2.0f, 2.0f, -1.5f, 1.5f); col(canvas);
+    plot(canvas, "normalize(p).x",  0.0f, 2.0f,  0.0f, 1.0f); col(canvas);
+    plot(canvas, "normalize(p).y",  0.0f, 2.0f,  0.0f, 1.0f); col(canvas);
+
+    plot(canvas, "faceforward(v1, p.x0, v1.x0).x", -1.0f, 1.0f, -1.5f, 1.5f, "faceforward"); row(canvas);
+
+    plot(canvas, "reflect(p.x1, v1.0x).x",         -1.0f, 1.0f, -1.0f, 1.0f, "reflect(horiz)"); col(canvas);
+    plot(canvas, "reflect(p.x1, normalize(v1)).y", -1.0f, 1.0f, -1.0f, 1.0f, "reflect(diag)" ); col(canvas);
+
+    plot(canvas, "refract(v1.x0, v1.0x, x).x", 0.0f, 1.0f, -1.0f, 1.0f, "refract().x"); col(canvas);
+    plot(canvas, "refract(v1.x0, v1.0x, x).y", 0.0f, 1.0f, -1.0f, 1.0f, "refract().y"); row(canvas);
+}
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 1eb0107..1c33a65 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -55,6 +55,7 @@
         { "ceil",        ByteCodeInstruction::kCeil },
         { "clamp",       SpecialIntrinsic::kClamp },
         { "cos",         ByteCodeInstruction::kCos },
+        { "distance",    SpecialIntrinsic::kDistance },
         { "dot",         SpecialIntrinsic::kDot },
         { "exp",         ByteCodeInstruction::kExp },
         { "exp2",        ByteCodeInstruction::kExp2 },
@@ -1248,6 +1249,19 @@
     }
 
     if (intrin.is_special) {
+        auto doDotProduct = [count, this] {
+            this->write(ByteCodeInstruction::kMultiplyF, count);
+            for (int i = count - 1; i-- > 0;) {
+                this->write(ByteCodeInstruction::kAddF, 1);
+            }
+        };
+
+        auto doLength = [count, this, &doDotProduct] {
+            this->write(ByteCodeInstruction::kDup, count);
+            doDotProduct();
+            this->write(ByteCodeInstruction::kSqrt, 1);
+        };
+
         switch (intrin.special) {
             case SpecialIntrinsic::kAll: {
                 for (int i = count-1; i --> 0;) {
@@ -1268,23 +1282,20 @@
                             count);
             } break;
 
+            case SpecialIntrinsic::kDistance: {
+                SkASSERT(nargs == 2 && count == SlotCount(args[1]->type()));
+                this->write(ByteCodeInstruction::kSubtractF, count);
+                doLength();
+            } break;
+
             case SpecialIntrinsic::kDot: {
-                SkASSERT(nargs == 2);
-                SkASSERT(count == SlotCount(args[1]->type()));
-                this->write(ByteCodeInstruction::kMultiplyF, count);
-                for (int i = count-1; i --> 0;) {
-                    this->write(ByteCodeInstruction::kAddF, 1);
-                }
+                SkASSERT(nargs == 2 && count == SlotCount(args[1]->type()));
+                doDotProduct();
             } break;
 
             case SpecialIntrinsic::kLength: {
                 SkASSERT(nargs == 1);
-                this->write(ByteCodeInstruction::kDup, count);
-                this->write(ByteCodeInstruction::kMultiplyF, count);
-                for (int i = count-1; i --> 0;) {
-                    this->write(ByteCodeInstruction::kAddF, 1);
-                }
-                this->write(ByteCodeInstruction::kSqrt, 1);
+                doLength();
             } break;
 
             case SpecialIntrinsic::kMax:
@@ -1334,12 +1345,7 @@
             case SpecialIntrinsic::kNormalize: {
                 SkASSERT(nargs == 1);
                 this->write(ByteCodeInstruction::kDup, count);
-                this->write(ByteCodeInstruction::kDup, count);
-                this->write(ByteCodeInstruction::kMultiplyF, count);
-                for (int i = count-1; i --> 0;) {
-                    this->write(ByteCodeInstruction::kAddF, 1);
-                }
-                this->write(ByteCodeInstruction::kSqrt, 1);
+                doLength();
                 dupSmallerType(1);
                 this->write(ByteCodeInstruction::kDivideF, count);
             } break;
diff --git a/src/sksl/SkSLByteCodeGenerator.h b/src/sksl/SkSLByteCodeGenerator.h
index 43ccbec..6fefa0a 100644
--- a/src/sksl/SkSLByteCodeGenerator.h
+++ b/src/sksl/SkSLByteCodeGenerator.h
@@ -140,6 +140,7 @@
         kAny,
         kATan,
         kClamp,
+        kDistance,
         kDot,
         kLength,
         kMax,
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index ef3daa3..7d67e9c 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -743,6 +743,11 @@
             return result;
         }
         case kSPIRV_IntrinsicKind: {
+            // GLSL supports dot(float, float), but SPIR-V does not. Convert it to FMul
+            if (intrinsicId == SpvOpDot &&
+                arguments[0]->type().typeKind() == Type::TypeKind::kScalar) {
+                intrinsicId = SpvOpFMul;
+            }
             SpvId result = this->nextId();
             std::vector<SpvId> argumentIds;
             for (size_t i = 0; i < arguments.size(); i++) {
diff --git a/src/sksl/generated/sksl_public.dehydrated.sksl b/src/sksl/generated/sksl_public.dehydrated.sksl
index 821fcd6..a37a8ae 100644
--- a/src/sksl/generated/sksl_public.dehydrated.sksl
+++ b/src/sksl/generated/sksl_public.dehydrated.sksl
@@ -1,4 +1,4 @@
-static uint8_t SKSL_INCLUDE_sksl_public[] = {252,1,
+static uint8_t SKSL_INCLUDE_sksl_public[] = {45,2,
 3,100,101,103,
 5,102,108,111,97,116,
 7,114,97,100,105,97,110,115,
@@ -47,11 +47,20 @@
 5,101,100,103,101,49,
 10,115,109,111,111,116,104,115,116,101,112,
 6,108,101,110,103,116,104,
-1,98,
+2,112,48,
+2,112,49,
 8,100,105,115,116,97,110,99,101,
 3,100,111,116,
+1,98,
 5,99,114,111,115,115,
 9,110,111,114,109,97,108,105,122,101,
+1,78,
+1,73,
+4,78,114,101,102,
+11,102,97,99,101,102,111,114,119,97,114,100,
+7,114,101,102,108,101,99,116,
+3,101,116,97,
+7,114,101,102,114,97,99,116,
 1,109,
 8,102,108,111,97,116,50,120,50,
 7,105,110,118,101,114,115,101,
@@ -77,8 +86,9 @@
 5,104,97,108,102,52,
 8,117,110,112,114,101,109,117,108,
 14,117,110,112,114,101,109,117,108,95,102,108,111,97,116,
+1,107,
 5,104,97,108,102,51,
-43,96,1,
+43,145,1,
 47,1,0,
 9,2,0,
 44,2,0,6,0,3,
@@ -857,363 +867,534 @@
 41,138,0,
 41,0,1,
 47,1,1,
-9,229,0,
-41,5,0,3,
-47,2,1,
 9,19,1,
-41,5,0,3,
+41,28,0,3,
+47,2,1,
+9,22,1,
+41,28,0,3,
 23,3,1,
-9,21,1,2,1,1,2,1,
+9,25,1,2,1,1,2,1,
 41,2,0,
 47,4,1,
-9,229,0,
-41,9,0,3,
-47,5,1,
 9,19,1,
-41,9,0,3,
+41,31,0,3,
+47,5,1,
+9,22,1,
+41,31,0,3,
 46,6,1,2,
 41,3,1,
 23,7,1,
-9,21,1,2,4,1,5,1,
-41,2,0,
+9,25,1,2,4,1,5,1,
+41,138,0,
 41,7,1,
 47,8,1,
-9,229,0,
-41,13,0,3,
+9,90,0,
+41,28,0,3,
 47,9,1,
-9,19,1,
-41,13,0,3,
-46,10,1,3,
-41,3,1,
-41,7,1,
-23,11,1,
-9,21,1,2,8,1,9,1,
+9,102,0,
+41,28,0,3,
+23,10,1,
+9,34,1,2,8,1,9,1,
 41,2,0,
-41,11,1,
+47,11,1,
+9,90,0,
+41,31,0,3,
 47,12,1,
-9,90,0,
-41,28,0,3,
-47,13,1,
 9,102,0,
-41,28,0,3,
+41,31,0,3,
+46,13,1,2,
+41,10,1,
 23,14,1,
-9,30,1,2,12,1,13,1,
-41,2,0,
-47,15,1,
-9,90,0,
-41,31,0,3,
-47,16,1,
-9,102,0,
-41,31,0,3,
-46,17,1,2,
-41,14,1,
-23,18,1,
-9,30,1,2,15,1,16,1,
+9,34,1,2,11,1,12,1,
 41,138,0,
-41,18,1,
-47,19,1,
+41,14,1,
+47,15,1,
 9,229,0,
 41,9,0,3,
-47,20,1,
-9,19,1,
+47,16,1,
+9,38,1,
 41,9,0,3,
-23,21,1,
-9,34,1,2,19,1,20,1,
+23,17,1,
+31,
+8,0,0,2,0,40,1,2,15,1,16,1,
 41,9,0,
-47,22,1,
+47,18,1,
 9,90,0,
 41,28,0,3,
-23,23,1,
-9,40,1,1,22,1,
+23,19,1,
+9,46,1,1,18,1,
 41,28,0,
-47,24,1,
+47,20,1,
 9,90,0,
 41,31,0,3,
-46,25,1,2,
-41,23,1,
-23,26,1,
-9,40,1,1,24,1,
+46,21,1,2,
+41,19,1,
+23,22,1,
+9,46,1,1,20,1,
 41,31,0,
-41,26,1,
+41,22,1,
+47,23,1,
+9,56,1,
+41,2,0,3,
+47,24,1,
+9,58,1,
+41,2,0,3,
+47,25,1,
+9,60,1,
+41,2,0,3,
+23,26,1,
+31,
+8,0,0,2,0,65,1,3,23,1,24,1,25,1,
+41,2,0,
 47,27,1,
-9,50,1,
-44,28,1,52,1,3,
-23,29,1,
-9,61,1,1,27,1,
-41,28,1,
-47,30,1,
-9,50,1,
-44,31,1,69,1,3,
-46,32,1,2,
-41,29,1,
-23,33,1,
-9,61,1,1,30,1,
+9,56,1,
+41,5,0,3,
+47,28,1,
+9,58,1,
+41,5,0,3,
+47,29,1,
+9,60,1,
+41,5,0,3,
+46,30,1,2,
+41,26,1,
+23,31,1,
+31,
+8,0,0,2,0,65,1,3,27,1,28,1,29,1,
+41,5,0,
 41,31,1,
-41,33,1,
+47,32,1,
+9,56,1,
+41,9,0,3,
+47,33,1,
+9,58,1,
+41,9,0,3,
 47,34,1,
-9,50,1,
-44,35,1,78,1,3,
-46,36,1,3,
-41,29,1,
-41,33,1,
-23,37,1,
-9,61,1,1,34,1,
-41,35,1,
-41,37,1,
+9,60,1,
+41,9,0,3,
+46,35,1,3,
+41,26,1,
+41,31,1,
+23,36,1,
+31,
+8,0,0,2,0,65,1,3,32,1,33,1,34,1,
+41,9,0,
+41,36,1,
+47,37,1,
+9,56,1,
+41,13,0,3,
 47,38,1,
-9,50,1,
-44,39,1,87,1,3,
+9,58,1,
+41,13,0,3,
+47,39,1,
+9,60,1,
+41,13,0,3,
 46,40,1,4,
-41,29,1,
-41,33,1,
-41,37,1,
+41,26,1,
+41,31,1,
+41,36,1,
 23,41,1,
-9,61,1,1,38,1,
-41,39,1,
+31,
+8,0,0,2,0,65,1,3,37,1,38,1,39,1,
+41,13,0,
 41,41,1,
 47,42,1,
-9,50,1,
-44,43,1,95,1,3,
-46,44,1,5,
-41,29,1,
-41,33,1,
-41,37,1,
-41,41,1,
-23,45,1,
-9,61,1,1,42,1,
-41,43,1,
-41,45,1,
+9,58,1,
+41,2,0,3,
+47,43,1,
+9,56,1,
+41,2,0,3,
+23,44,1,
+31,
+8,0,0,2,0,77,1,2,42,1,43,1,
+41,2,0,
+47,45,1,
+9,58,1,
+41,5,0,3,
 47,46,1,
-9,50,1,
-44,47,1,103,1,3,
-46,48,1,6,
-41,29,1,
-41,33,1,
-41,37,1,
-41,41,1,
-41,45,1,
-23,49,1,
-9,61,1,1,46,1,
-41,47,1,
-41,49,1,
+9,56,1,
+41,5,0,3,
+46,47,1,2,
+41,44,1,
+23,48,1,
+31,
+8,0,0,2,0,77,1,2,45,1,46,1,
+41,5,0,
+41,48,1,
+47,49,1,
+9,58,1,
+41,9,0,3,
 47,50,1,
-9,90,0,
-44,51,1,111,1,3,
-47,52,1,
-9,102,0,
-41,51,1,3,
-23,53,1,
-9,116,1,2,50,1,52,1,
-44,54,1,125,1,
-47,55,1,
-9,90,0,
-44,56,1,131,1,3,
+9,56,1,
+41,9,0,3,
+46,51,1,3,
+41,44,1,
+41,48,1,
+23,52,1,
+31,
+8,0,0,2,0,77,1,2,49,1,50,1,
+41,9,0,
+41,52,1,
+47,53,1,
+9,58,1,
+41,13,0,3,
+47,54,1,
+9,56,1,
+41,13,0,3,
+46,55,1,4,
+41,44,1,
+41,48,1,
+41,52,1,
+23,56,1,
+31,
+8,0,0,2,0,77,1,2,53,1,54,1,
+41,13,0,
+41,56,1,
 47,57,1,
-9,102,0,
-41,56,1,3,
-46,58,1,2,
-41,53,1,
-23,59,1,
-9,116,1,2,55,1,57,1,
-41,54,1,
-41,59,1,
-47,60,1,
-9,90,0,
-41,51,1,3,
+9,58,1,
+41,2,0,3,
+47,58,1,
+9,56,1,
+41,2,0,3,
+47,59,1,
+9,85,1,
+41,2,0,3,
+23,60,1,
+31,
+8,0,0,2,0,89,1,3,57,1,58,1,59,1,
+41,2,0,
 47,61,1,
-9,102,0,
-41,51,1,3,
-23,62,1,
-9,137,1,2,60,1,61,1,
-41,54,1,
+9,58,1,
+41,5,0,3,
+47,62,1,
+9,56,1,
+41,5,0,3,
 47,63,1,
-9,90,0,
-41,56,1,3,
-47,64,1,
-9,102,0,
-41,56,1,3,
-46,65,1,2,
-41,62,1,
-23,66,1,
-9,137,1,2,63,1,64,1,
-41,54,1,
-41,66,1,
+9,85,1,
+41,2,0,3,
+46,64,1,2,
+41,60,1,
+23,65,1,
+31,
+8,0,0,2,0,89,1,3,61,1,62,1,63,1,
+41,5,0,
+41,65,1,
+47,66,1,
+9,58,1,
+41,9,0,3,
 47,67,1,
-9,90,0,
-41,51,1,3,
+9,56,1,
+41,9,0,3,
 47,68,1,
-9,102,0,
-41,51,1,3,
-23,69,1,
-9,151,1,2,67,1,68,1,
-41,54,1,
-47,70,1,
-9,90,0,
-41,56,1,3,
+9,85,1,
+41,2,0,3,
+46,69,1,3,
+41,60,1,
+41,65,1,
+23,70,1,
+31,
+8,0,0,2,0,89,1,3,66,1,67,1,68,1,
+41,9,0,
+41,70,1,
 47,71,1,
-9,102,0,
-41,56,1,3,
-46,72,1,2,
-41,69,1,
-23,73,1,
-9,151,1,2,70,1,71,1,
-41,54,1,
-41,73,1,
-47,74,1,
-9,90,0,
-41,51,1,3,
-47,75,1,
-9,102,0,
-41,51,1,3,
-23,76,1,
-9,163,1,2,74,1,75,1,
-41,54,1,
-47,77,1,
-9,90,0,
-41,56,1,3,
-47,78,1,
-9,102,0,
-41,56,1,3,
-46,79,1,2,
-41,76,1,
-23,80,1,
-9,163,1,2,77,1,78,1,
-41,54,1,
+9,58,1,
+41,13,0,3,
+47,72,1,
+9,56,1,
+41,13,0,3,
+47,73,1,
+9,85,1,
+41,2,0,3,
+46,74,1,4,
+41,60,1,
+41,65,1,
+41,70,1,
+23,75,1,
+31,
+8,0,0,2,0,89,1,3,71,1,72,1,73,1,
+41,13,0,
+41,75,1,
+47,76,1,
+9,97,1,
+44,77,1,99,1,3,
+23,78,1,
+9,108,1,1,76,1,
+41,77,1,
+47,79,1,
+9,97,1,
+44,80,1,116,1,3,
+46,81,1,2,
+41,78,1,
+23,82,1,
+9,108,1,1,79,1,
 41,80,1,
-47,81,1,
-9,90,0,
-41,51,1,3,
-47,82,1,
-9,102,0,
-41,51,1,3,
-23,83,1,
-9,180,1,2,81,1,82,1,
-41,54,1,
-47,84,1,
-9,90,0,
-41,56,1,3,
-47,85,1,
-9,102,0,
-41,56,1,3,
-46,86,1,2,
-41,83,1,
-23,87,1,
-9,180,1,2,84,1,85,1,
-41,54,1,
-41,87,1,
-47,88,1,
-9,90,0,
-41,54,1,3,
-47,89,1,
-9,102,0,
-41,54,1,3,
-46,90,1,3,
-41,83,1,
-41,87,1,
-23,91,1,
-9,180,1,2,88,1,89,1,
-41,54,1,
-41,91,1,
-47,92,1,
-9,90,0,
-41,51,1,3,
-47,93,1,
-9,102,0,
-41,51,1,3,
+41,82,1,
+47,83,1,
+9,97,1,
+44,84,1,125,1,3,
+46,85,1,3,
+41,78,1,
+41,82,1,
+23,86,1,
+9,108,1,1,83,1,
+41,84,1,
+41,86,1,
+47,87,1,
+9,97,1,
+44,88,1,134,1,3,
+46,89,1,4,
+41,78,1,
+41,82,1,
+41,86,1,
+23,90,1,
+9,108,1,1,87,1,
+41,88,1,
+41,90,1,
+47,91,1,
+9,97,1,
+44,92,1,142,1,3,
+46,93,1,5,
+41,78,1,
+41,82,1,
+41,86,1,
+41,90,1,
 23,94,1,
-9,186,1,2,92,1,93,1,
-41,54,1,
+9,108,1,1,91,1,
+41,92,1,
+41,94,1,
 47,95,1,
-9,90,0,
-41,56,1,3,
-47,96,1,
-9,102,0,
-41,56,1,3,
-46,97,1,2,
+9,97,1,
+44,96,1,150,1,3,
+46,97,1,6,
+41,78,1,
+41,82,1,
+41,86,1,
+41,90,1,
 41,94,1,
 23,98,1,
-9,186,1,2,95,1,96,1,
-41,54,1,
+9,108,1,1,95,1,
+41,96,1,
 41,98,1,
 47,99,1,
 9,90,0,
-41,54,1,3,
-47,100,1,
+44,100,1,158,1,3,
+47,101,1,
 9,102,0,
-41,54,1,3,
-46,101,1,3,
-41,94,1,
-41,98,1,
+41,100,1,3,
 23,102,1,
-9,186,1,2,99,1,100,1,
-41,54,1,
-41,102,1,
-47,103,1,
+9,163,1,2,99,1,101,1,
+44,103,1,172,1,
+47,104,1,
 9,90,0,
-41,54,1,3,
-23,104,1,
-9,195,1,1,103,1,
-44,105,1,199,1,
+44,105,1,178,1,3,
 47,106,1,
+9,102,0,
+41,105,1,3,
+46,107,1,2,
+41,102,1,
+23,108,1,
+9,163,1,2,104,1,106,1,
+41,103,1,
+41,108,1,
+47,109,1,
 9,90,0,
-41,54,1,3,
-23,107,1,
-9,204,1,1,106,1,
-41,105,1,
-47,108,1,
-9,90,0,
-41,54,1,3,
-23,109,1,
-9,208,1,1,108,1,
-41,54,1,
+41,100,1,3,
 47,110,1,
-9,212,1,
-44,111,1,218,1,3,
-23,112,1,
-9,224,1,1,110,1,
-41,111,1,
+9,102,0,
+41,100,1,3,
+23,111,1,
+9,184,1,2,109,1,110,1,
+41,103,1,
+47,112,1,
+9,90,0,
+41,105,1,3,
 47,113,1,
-9,212,1,
+9,102,0,
+41,105,1,3,
+46,114,1,2,
+41,111,1,
+23,115,1,
+9,184,1,2,112,1,113,1,
+41,103,1,
+41,115,1,
+47,116,1,
+9,90,0,
+41,100,1,3,
+47,117,1,
+9,102,0,
+41,100,1,3,
+23,118,1,
+9,198,1,2,116,1,117,1,
+41,103,1,
+47,119,1,
+9,90,0,
+41,105,1,3,
+47,120,1,
+9,102,0,
+41,105,1,3,
+46,121,1,2,
+41,118,1,
+23,122,1,
+9,198,1,2,119,1,120,1,
+41,103,1,
+41,122,1,
+47,123,1,
+9,90,0,
+41,100,1,3,
+47,124,1,
+9,102,0,
+41,100,1,3,
+23,125,1,
+9,210,1,2,123,1,124,1,
+41,103,1,
+47,126,1,
+9,90,0,
+41,105,1,3,
+47,127,1,
+9,102,0,
+41,105,1,3,
+46,128,1,2,
+41,125,1,
+23,129,1,
+9,210,1,2,126,1,127,1,
+41,103,1,
+41,129,1,
+47,130,1,
+9,90,0,
+41,100,1,3,
+47,131,1,
+9,102,0,
+41,100,1,3,
+23,132,1,
+9,227,1,2,130,1,131,1,
+41,103,1,
+47,133,1,
+9,90,0,
+41,105,1,3,
+47,134,1,
+9,102,0,
+41,105,1,3,
+46,135,1,2,
+41,132,1,
+23,136,1,
+9,227,1,2,133,1,134,1,
+41,103,1,
+41,136,1,
+47,137,1,
+9,90,0,
+41,103,1,3,
+47,138,1,
+9,102,0,
+41,103,1,3,
+46,139,1,3,
+41,132,1,
+41,136,1,
+23,140,1,
+9,227,1,2,137,1,138,1,
+41,103,1,
+41,140,1,
+47,141,1,
+9,90,0,
+41,100,1,3,
+47,142,1,
+9,102,0,
+41,100,1,3,
+23,143,1,
+9,233,1,2,141,1,142,1,
+41,103,1,
+47,144,1,
+9,90,0,
+41,105,1,3,
+47,145,1,
+9,102,0,
+41,105,1,3,
+46,146,1,2,
+41,143,1,
+23,147,1,
+9,233,1,2,144,1,145,1,
+41,103,1,
+41,147,1,
+47,148,1,
+9,90,0,
+41,103,1,3,
+47,149,1,
+9,102,0,
+41,103,1,3,
+46,150,1,3,
+41,143,1,
+41,147,1,
+23,151,1,
+9,233,1,2,148,1,149,1,
+41,103,1,
+41,151,1,
+47,152,1,
+9,90,0,
+41,103,1,3,
+23,153,1,
+9,242,1,1,152,1,
+44,154,1,246,1,
+47,155,1,
+9,90,0,
+41,103,1,3,
+23,156,1,
+9,251,1,1,155,1,
+41,154,1,
+47,157,1,
+9,90,0,
+41,103,1,3,
+23,158,1,
+9,255,1,1,157,1,
+41,103,1,
+47,159,1,
+9,3,2,
+44,160,1,9,2,3,
+23,161,1,
+9,15,2,1,159,1,
+41,160,1,
+47,162,1,
+9,3,2,
 41,13,0,3,
-23,114,1,
-9,233,1,1,113,1,
-41,13,0,45,0,
+23,163,1,
+9,24,2,1,162,1,
+41,13,0,48,0,
 100,0,
 45,0,
-89,1,
-87,1,
+138,1,
+136,1,
 40,0,
 58,0,
 115,0,
 184,0,
 30,0,
-13,1,
-20,0,
-2,1,
 9,1,
-73,1,
+20,0,
+254,0,
+5,1,
+122,1,
 70,0,
 80,0,
+32,1,
 110,0,
 120,0,
-55,1,
-62,1,
-34,1,
+104,1,
+111,1,
+83,1,
 95,0,
 247,0,
-41,1,
-48,1,
+90,1,
+97,1,
 75,0,
 85,0,
 165,0,
 150,0,
 208,0,
 135,0,
-17,1,
-91,1,
-84,1,
+13,1,
+140,1,
+133,1,
 65,0,
 9,0,
+47,1,
+66,1,
 189,0,
 105,0,
 25,0,
@@ -1221,8 +1402,8 @@
 90,0,
 223,0,
 35,0,
-93,1,
-95,1,
+142,1,
+144,1,
 12,
 22,3,0,
 2,
@@ -1296,37 +1477,7 @@
 19,
 41,2,0,225,46,101,66,
 41,13,0,1,0,
-22,3,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,2,0,253,0,1,
-1,
-50,1,1,0,58,
-50,2,1,0,
-41,5,0,1,0,
-22,7,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,2,0,253,0,1,
-1,
-50,4,1,0,58,
-50,5,1,0,
-41,9,0,1,0,
-22,11,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,2,0,253,0,1,
-1,
-50,8,1,0,58,
-50,9,1,0,
-41,13,0,1,0,
-22,21,1,
+22,17,1,
 2,
 43,0,0,0,0,1,
 36,
@@ -1335,64 +1486,458 @@
 1,
 1,
 40,
-50,19,1,0,1,1,59,
+50,15,1,0,1,1,59,
 40,
-50,20,1,0,1,2,
+50,16,1,0,1,2,
 41,2,0,58,
 1,
 40,
-50,19,1,0,1,2,59,
+50,15,1,0,1,2,59,
 40,
-50,20,1,0,1,1,
+50,16,1,0,1,1,
 41,2,0,
 41,2,0,
 1,
 1,
 40,
-50,19,1,0,1,2,59,
+50,15,1,0,1,2,59,
 40,
-50,20,1,0,1,0,
+50,16,1,0,1,0,
 41,2,0,58,
 1,
 40,
-50,19,1,0,1,0,59,
+50,15,1,0,1,0,59,
 40,
-50,20,1,0,1,2,
+50,16,1,0,1,2,
 41,2,0,
 41,2,0,
 1,
 1,
 40,
-50,19,1,0,1,0,59,
+50,15,1,0,1,0,59,
 40,
-50,20,1,0,1,1,
+50,16,1,0,1,1,
 41,2,0,58,
 1,
 40,
-50,19,1,0,1,1,59,
+50,15,1,0,1,1,59,
 40,
-50,20,1,0,1,0,
+50,16,1,0,1,0,
 41,2,0,
 41,2,0,1,0,
-22,112,1,
+22,26,1,
+2,
+43,0,0,0,0,1,
+36,
+45,
+1,
+21,
+41,2,0,10,1,2,
+50,25,1,0,
+50,24,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+50,23,1,0,
+35,58,
+50,23,1,0,1,0,
+22,31,1,
+2,
+43,0,0,0,0,1,
+36,
+45,
+1,
+21,
+41,2,0,10,1,2,
+50,29,1,0,
+50,28,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+50,27,1,0,
+35,58,
+50,27,1,0,1,0,
+22,36,1,
+2,
+43,0,0,0,0,1,
+36,
+45,
+1,
+21,
+41,2,0,10,1,2,
+50,34,1,0,
+50,33,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+50,32,1,0,
+35,58,
+50,32,1,0,1,0,
+22,41,1,
+2,
+43,0,0,0,0,1,
+36,
+45,
+1,
+21,
+41,2,0,10,1,2,
+50,39,1,0,
+50,38,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+50,37,1,0,
+35,58,
+50,37,1,0,1,0,
+22,44,1,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,42,1,0,58,
+1,
+1,
+19,
+41,2,0,0,0,0,64,59,
+21,
+41,2,0,10,1,2,
+50,43,1,0,
+50,42,1,0,
+41,2,0,59,
+50,43,1,0,
+41,2,0,
+41,2,0,1,0,
+22,48,1,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,45,1,0,58,
+1,
+1,
+19,
+41,2,0,0,0,0,64,59,
+21,
+41,2,0,10,1,2,
+50,46,1,0,
+50,45,1,0,
+41,2,0,59,
+50,46,1,0,
+41,5,0,
+41,5,0,1,0,
+22,52,1,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,49,1,0,58,
+1,
+1,
+19,
+41,2,0,0,0,0,64,59,
+21,
+41,2,0,10,1,2,
+50,50,1,0,
+50,49,1,0,
+41,2,0,59,
+50,50,1,0,
+41,9,0,
+41,9,0,1,0,
+22,56,1,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,53,1,0,58,
+1,
+1,
+19,
+41,2,0,0,0,0,64,59,
+21,
+41,2,0,10,1,2,
+50,54,1,0,
+50,53,1,0,
+41,2,0,59,
+50,54,1,0,
+41,13,0,
+41,13,0,1,0,
+22,60,1,
+2,
+43,1,0,
+47,164,1,
+9,39,2,
+41,2,0,2,1,0,
+0,0,2,
+48,164,1,
+41,2,0,0,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+1,
+50,59,1,0,59,
+50,59,1,0,
+41,2,0,59,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+21,
+41,2,0,10,1,2,
+50,58,1,0,
+50,57,1,0,59,
+21,
+41,2,0,10,1,2,
+50,58,1,0,
+50,57,1,0,
+41,2,0,
+41,2,0,
+41,2,0,
+41,2,0,
+36,
+45,
+1,
+50,164,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+19,
+41,2,0,0,0,0,0,
+1,
+1,
+50,59,1,0,59,
+50,57,1,0,
+41,2,0,58,
+1,
+1,
+1,
+50,59,1,0,59,
+21,
+41,2,0,10,1,2,
+50,58,1,0,
+50,57,1,0,
+41,2,0,57,
+21,
+41,2,0,95,0,1,
+50,164,1,0,
+41,2,0,59,
+50,58,1,0,
+41,2,0,
+41,2,0,1,0,
+22,65,1,
+2,
+43,1,0,
+47,165,1,
+9,39,2,
+41,2,0,2,1,0,
+0,0,2,
+48,165,1,
+41,2,0,0,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+1,
+50,63,1,0,59,
+50,63,1,0,
+41,2,0,59,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+21,
+41,2,0,10,1,2,
+50,62,1,0,
+50,61,1,0,59,
+21,
+41,2,0,10,1,2,
+50,62,1,0,
+50,61,1,0,
+41,2,0,
+41,2,0,
+41,2,0,
+41,2,0,
+36,
+45,
+1,
+50,165,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+6,
+41,5,0,1,
+19,
+41,2,0,0,0,0,0,
+1,
+1,
+50,63,1,0,59,
+50,61,1,0,
+41,5,0,58,
+1,
+1,
+1,
+50,63,1,0,59,
+21,
+41,2,0,10,1,2,
+50,62,1,0,
+50,61,1,0,
+41,2,0,57,
+21,
+41,2,0,95,0,1,
+50,165,1,0,
+41,2,0,59,
+50,62,1,0,
+41,5,0,
+41,5,0,1,0,
+22,70,1,
+2,
+43,1,0,
+47,166,1,
+9,39,2,
+41,2,0,2,1,0,
+0,0,2,
+48,166,1,
+41,2,0,0,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+1,
+50,68,1,0,59,
+50,68,1,0,
+41,2,0,59,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+21,
+41,2,0,10,1,2,
+50,67,1,0,
+50,66,1,0,59,
+21,
+41,2,0,10,1,2,
+50,67,1,0,
+50,66,1,0,
+41,2,0,
+41,2,0,
+41,2,0,
+41,2,0,
+36,
+45,
+1,
+50,166,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+6,
+41,9,0,1,
+19,
+41,2,0,0,0,0,0,
+1,
+1,
+50,68,1,0,59,
+50,66,1,0,
+41,9,0,58,
+1,
+1,
+1,
+50,68,1,0,59,
+21,
+41,2,0,10,1,2,
+50,67,1,0,
+50,66,1,0,
+41,2,0,57,
+21,
+41,2,0,95,0,1,
+50,166,1,0,
+41,2,0,59,
+50,67,1,0,
+41,9,0,
+41,9,0,1,0,
+22,75,1,
+2,
+43,1,0,
+47,167,1,
+9,39,2,
+41,2,0,2,1,0,
+0,0,2,
+48,167,1,
+41,2,0,0,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+1,
+50,73,1,0,59,
+50,73,1,0,
+41,2,0,59,
+1,
+19,
+41,2,0,0,0,128,63,58,
+1,
+21,
+41,2,0,10,1,2,
+50,72,1,0,
+50,71,1,0,59,
+21,
+41,2,0,10,1,2,
+50,72,1,0,
+50,71,1,0,
+41,2,0,
+41,2,0,
+41,2,0,
+41,2,0,
+36,
+45,
+1,
+50,167,1,0,79,
+19,
+41,2,0,0,0,0,0,
+41,154,1,
+6,
+41,13,0,1,
+19,
+41,2,0,0,0,0,0,
+1,
+1,
+50,73,1,0,59,
+50,71,1,0,
+41,13,0,58,
+1,
+1,
+1,
+50,73,1,0,59,
+21,
+41,2,0,10,1,2,
+50,72,1,0,
+50,71,1,0,
+41,2,0,57,
+21,
+41,2,0,95,0,1,
+50,167,1,0,
+41,2,0,59,
+50,72,1,0,
+41,13,0,
+41,13,0,1,0,
+22,161,1,
 2,
 43,0,0,0,0,1,
 36,
 6,
-41,111,1,2,
+41,160,1,2,
 1,
 40,
-50,110,1,0,3,0,1,2,60,
+50,159,1,0,3,0,1,2,60,
 21,
 41,138,0,170,0,2,
 40,
-50,110,1,0,1,3,
+50,159,1,0,1,3,
 19,
 41,138,0,23,183,209,56,
-44,115,1,248,1,
+44,168,1,41,2,
 40,
-50,110,1,0,1,3,1,0,
-22,114,1,
+50,159,1,0,1,3,1,0,
+22,163,1,
 2,
 43,0,0,0,0,1,
 36,
@@ -1400,15 +1945,15 @@
 41,13,0,2,
 1,
 40,
-50,113,1,0,3,0,1,2,60,
+50,162,1,0,3,0,1,2,60,
 21,
 41,2,0,162,0,2,
 40,
-50,113,1,0,1,3,
+50,162,1,0,1,3,
 19,
 41,2,0,23,183,209,56,
 41,9,0,
 40,
-50,113,1,0,1,3,1,0,
+50,162,1,0,1,3,1,0,
 13,};
 static constexpr size_t SKSL_INCLUDE_sksl_public_LENGTH = sizeof(SKSL_INCLUDE_sksl_public);
diff --git a/src/sksl/sksl_public.sksl b/src/sksl/sksl_public.sksl
index 5b31ab4..46ecb3a 100644
--- a/src/sksl/sksl_public.sksl
+++ b/src/sksl/sksl_public.sksl
@@ -93,15 +93,12 @@
 // 8.4 : Geometric Functions
 float length($genType  x);
 half  length($genHType x);
-
-float distance(float2 a, float2 b) { return length(a - b); }
-float distance(float3 a, float3 b) { return length(a - b); }
-float distance(float4 a, float4 b) { return length(a - b); }
-
+float distance($genType  p0, $genType  p1);
+half  distance($genHType p0, $genHType p1);
 float dot($genType  x, $genType  y);
 half  dot($genHType x, $genHType y);
 
-float3 cross(float3 a, float3 b) {
+inline float3 cross(float3 a, float3 b) {
     return float3(a.y * b.z - a.z * b.y,
                   a.z * b.x - a.x * b.z,
                   a.x * b.y - a.y * b.x);
@@ -109,9 +106,37 @@
 
 $genType  normalize($genType  x);
 $genHType normalize($genHType x);
-// TODO: faceforward(N, I, Nref)
-// TODO: reflect(I, N)
-// TODO: refract(I, N, eta)
+
+inline float  faceforward(float  N, float  I, float  Nref) { return dot(Nref, I) < 0 ? N : -N; }
+inline float2 faceforward(float2 N, float2 I, float2 Nref) { return dot(Nref, I) < 0 ? N : -N; }
+inline float3 faceforward(float3 N, float3 I, float3 Nref) { return dot(Nref, I) < 0 ? N : -N; }
+inline float4 faceforward(float4 N, float4 I, float4 Nref) { return dot(Nref, I) < 0 ? N : -N; }
+
+inline float  reflect(float  I, float  N) { return I - 2 * dot(N, I) * N; }
+inline float2 reflect(float2 I, float2 N) { return I - 2 * dot(N, I) * N; }
+inline float3 reflect(float3 I, float3 N) { return I - 2 * dot(N, I) * N; }
+inline float4 reflect(float4 I, float4 N) { return I - 2 * dot(N, I) * N; }
+
+inline float refract(float I, float N, float eta) {
+    float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
+    return k < 0 ? float(0)
+                 : eta * I - (eta * dot(N, I) + sqrt(k)) * N;
+}
+inline float2 refract(float2 I, float2 N, float eta) {
+    float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
+    return k < 0 ? float2(0)
+                 : eta * I - (eta * dot(N, I) + sqrt(k)) * N;
+}
+inline float3 refract(float3 I, float3 N, float eta) {
+    float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
+    return k < 0 ? float3(0)
+                 : eta * I - (eta * dot(N, I) + sqrt(k)) * N;
+}
+inline float4 refract(float4 I, float4 N, float eta) {
+    float k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
+    return k < 0 ? float4(0)
+                 : eta * I - (eta * dot(N, I) + sqrt(k)) * N;
+}
 
 // 8.5 : Matrix Functions
 // TODO: matrixCompMult(x, y)