Create vector swizzle operators in WSL's standard library
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Sep 2017 16:44:14 +0000 (16:44 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Sep 2017 16:44:14 +0000 (16:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177116

Reviewed by Filip Pizlo.

Because there are 481 possible swizzling operators, StandardLibrary.js generates them
instead of including them by hand.

Adding so many functions slows down the compiler quite a bit.

* WebGPUShadingLanguageRI/Prepare.js:
(prepare):
* WebGPUShadingLanguageRI/StandardLibrary.js:
(intToString):
(_generateSwizzle):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222267 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/WebGPUShadingLanguageRI/Prepare.js
Tools/WebGPUShadingLanguageRI/StandardLibrary.js
Tools/WebGPUShadingLanguageRI/Test.js

index dac65db..4065f58 100644 (file)
@@ -1,3 +1,21 @@
+2017-09-20  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Create vector swizzle operators in WSL's standard library
+        https://bugs.webkit.org/show_bug.cgi?id=177116
+
+        Reviewed by Filip Pizlo.
+
+        Because there are 481 possible swizzling operators, StandardLibrary.js generates them
+        instead of including them by hand.
+
+        Adding so many functions slows down the compiler quite a bit.
+
+        * WebGPUShadingLanguageRI/Prepare.js:
+        (prepare):
+        * WebGPUShadingLanguageRI/StandardLibrary.js:
+        (intToString):
+        (_generateSwizzle):
+
 2017-09-20  Ms2ger  <Ms2ger@igalia.com>
 
         [WPE] Update fontconfig to 2.12.4.
index 6b58a99..04d12f2 100644 (file)
@@ -29,7 +29,7 @@ let prepare = (() => {
     return (origin, lineNumberOffset, text) => {
         if (!standardProgram) {
             standardProgram = new Program();
-            parse(standardProgram, "/internal/stdlib", "native", 27, standardLibrary);
+            parse(standardProgram, "/internal/stdlib", "native", 72, standardLibrary);
         }
         
         let program = cloneProgram(standardProgram);
index 42b6ef9..cde5fc8 100644 (file)
  */
 "use strict";
 
-// NOTE: The next line is line 28, and we rely on this in Prepare.js.
+function intToString(x)
+{
+    switch (x) {
+    case 0:
+        return "x";
+    case 1:
+        return "y";
+    case 2:
+        return "z";
+    case 3:
+        return "w";
+    default:
+        throw new Error("Could not generate standard library.");
+    }
+}
+
+// There are 481 swizzle operators. Let's not list them explicitly.
+function _generateSwizzle(maxDepth, maxItems, array)
+{
+    if (!array)
+        array = [];
+    if (array.length == maxDepth) {
+        let result = `vec${array.length}<T> operator.${array.join("")}<T>(vec${maxItems}<T> v)
+{
+    vec${array.length}<T> result;
+`;
+        for (let i = 0; i < array.length; ++i) {
+            result += `    result.${intToString(i)} = v.${array[i]};
+`;
+        }
+        result += `    return result;
+}
+`;
+        return result;
+    }
+    let result = "";
+    for (let i = 0; i < maxItems; ++i) {
+        array.push(intToString(i));
+        result += _generateSwizzle(maxDepth, maxItems, array);
+        array.pop();
+    }
+    return result;
+}
+
+// NOTE: The next line is line 72, and we rely on this in Prepare.js.
 const standardLibrary = `
 // This is the WSL standard library. Implementations of all of these things are in
 // Intrinsics.js. The only thing that gets defined before we get here is the Primitive
@@ -353,4 +397,14 @@ uint operator.length<T, uint length>(T[length])
 {
     return length;
 }
+
+${_generateSwizzle(2, 2)}
+${_generateSwizzle(3, 2)}
+${_generateSwizzle(4, 2)}
+${_generateSwizzle(2, 3)}
+${_generateSwizzle(3, 3)}
+${_generateSwizzle(4, 3)}
+${_generateSwizzle(2, 4)}
+${_generateSwizzle(3, 4)}
+${_generateSwizzle(4, 4)}
 `;
index eea9880..a4df9b0 100644 (file)
@@ -4246,6 +4246,31 @@ function TEST_trap()
     }
 }
 
+function TEST_swizzle()
+{
+    let program = doPrep(`
+        float foo() {
+            float4 bar = float4(3., 4., 5., 6.);
+            float3 baz = bar.zzx;
+            return baz.z;
+        }
+        float foo2() {
+            float4 bar = float4(3., 4., 5., 6.);
+            float3 baz = bar.wyz;
+            return baz.x;
+        }
+        float foo3() {
+            float3 bar = float3(3., 4., 5.);
+            float2 baz = bar.yz;
+            float4 quix = baz.yyxx;
+            return quix.z;
+        }
+    `);
+    checkFloat(program, callFunction(program, "foo", [], []), 3);
+    checkFloat(program, callFunction(program, "foo2", [], []), 6);
+    checkFloat(program, callFunction(program, "foo3", [], []), 4);
+}
+
 let filter = /.*/; // run everything by default
 if (this["arguments"]) {
     for (let i = 0; i < arguments.length; i++) {