Title: [247130] trunk/LayoutTests
Revision
247130
Author
justin_...@apple.com
Date
2019-07-03 18:30:15 -0700 (Wed, 03 Jul 2019)

Log Message

[WHLSL] Support float4x4 in test harness
https://bugs.webkit.org/show_bug.cgi?id=199484

Reviewed by Myles C. Maxfield.

Support WHLSL float4x4 parameters in the WHLSL test harness.

* webgpu/js/whlsl-test-harness.js:
(isScalar):
(convertTypeToArrayType):
(convertTypeToWHLSLType):
(Data):
(makeFloat4):
(makeFloat4x4):
(processArrays):
(async.callFloat4x4Function):
(isVectorType): Deleted. Replaced with isScalar.

Add some float4x4 sanity checks:
* webgpu/whlsl-test-harness-test-expected.txt:
* webgpu/whlsl-test-harness-test.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (247129 => 247130)


--- trunk/LayoutTests/ChangeLog	2019-07-04 01:29:55 UTC (rev 247129)
+++ trunk/LayoutTests/ChangeLog	2019-07-04 01:30:15 UTC (rev 247130)
@@ -1,3 +1,27 @@
+2019-07-03  Justin Fan  <justin_...@apple.com>
+
+        [WHLSL] Support float4x4 in test harness
+        https://bugs.webkit.org/show_bug.cgi?id=199484
+
+        Reviewed by Myles C. Maxfield.
+
+        Support WHLSL float4x4 parameters in the WHLSL test harness.
+
+        * webgpu/js/whlsl-test-harness.js:
+        (isScalar):
+        (convertTypeToArrayType):
+        (convertTypeToWHLSLType):
+        (Data):
+        (makeFloat4):
+        (makeFloat4x4):
+        (processArrays):
+        (async.callFloat4x4Function):
+        (isVectorType): Deleted. Replaced with isScalar.
+
+        Add some float4x4 sanity checks:
+        * webgpu/whlsl-test-harness-test-expected.txt:
+        * webgpu/whlsl-test-harness-test.html:
+
 2019-07-03  Simon Fraser  <simon.fra...@apple.com>
 
         RELEASE_ASSERT in WebCore: WebCore::ScrollingStateTree::insertNode()

Modified: trunk/LayoutTests/webgpu/js/whlsl-test-harness.js (247129 => 247130)


--- trunk/LayoutTests/webgpu/js/whlsl-test-harness.js	2019-07-04 01:29:55 UTC (rev 247129)
+++ trunk/LayoutTests/webgpu/js/whlsl-test-harness.js	2019-07-04 01:30:15 UTC (rev 247130)
@@ -9,16 +9,18 @@
     UINT: Symbol("uint"),
     FLOAT: Symbol("float"),
     FLOAT4: Symbol("float4"),
-    MAX_SIZE: 16 // This needs to be big enough to hold any singular WHLSL type.
+    FLOAT4X4: Symbol("float4x4"),
+    MAX_SIZE: 64 // This needs to be big enough to hold any singular WHLSL type.
 });
 
-function isVectorType(type)
+function isScalar(type)
 {
     switch(type) {
         case Types.FLOAT4:
+        case Types.FLOAT4X4:
+            return false;
+        default:
             return true;
-        default: 
-            return false;
     }
 }
 
@@ -37,6 +39,7 @@
             return Uint32Array;
         case Types.FLOAT:
         case Types.FLOAT4:
+        case Types.FLOAT4X4:
             return Float32Array;
         default:
             throw new Error("Invalid TYPE provided!");
@@ -58,6 +61,8 @@
             return "float";
         case Types.FLOAT4:
             return "float4";
+        case Types.FLOAT4X4:
+            return "float4x4";
         default:
             throw new Error("Invalid TYPE provided!");
     }
@@ -107,7 +112,7 @@
         // However, vector types are also created via an array of scalars.
         // This ensures that buffers of just one vector are usable in a test function.
         if (Array.isArray(values))
-            this._isBuffer = isVectorType(type) ? isBuffer : true;
+            this._isBuffer = isScalar(type) ? true : isBuffer;
         else {
             this._isBuffer = false;
             values = [values];
@@ -434,13 +439,33 @@
  */
 function makeFloat4(values)
 {
+    const results = processArrays(values, 4);
+    return new Data(harness, Types.FLOAT4, results.values, results.isBuffer);
+}
+
+/**
+ * @param {Array or Array[Array]} values - 1D or 2D array of float values.
+ * The total number of float values must be divisible by 16.
+ * A single 16-element array of floats will be treated as a single float4x4 argument in the shader.
+ * This should follow the glMatrix/OpenGL method of storing 4x4 matrices,
+ * where the x, y, z translation components are the 13th, 14th, and 15th elements respectively.
+ */
+function makeFloat4x4(values)
+{
+    const results = processArrays(values, 16);
+    return new Data(harness, Types.FLOAT4X4, results.values, results.isBuffer);
+}
+
+function processArrays(values, minimumLength)
+{
     const originalLength = values.length;
     // This works because float4 is tightly packed.
     // When implementing other vector types, add padding if needed.
     values = values.flat();
-    if (values.length % 4 != 0)
-        throw new Error("makeFloat4: Invalid number of elements!");
-    return new Data(harness, Types.FLOAT4, values, originalLength === 1 || values.length > 4);
+    if (values.length % minimumLength != 0)
+        throw new Error("Invalid number of elements in non-scalar type!");
+    
+    return { values: values, isBuffer: originalLength === 1 || values.length > minimumLength };
 }
 
 /**
@@ -479,6 +504,11 @@
     return (await harness.callTypedFunction(Types.FLOAT4, functions, name, args)).subarray(0, 4);
 }
 
+async function callFloat4x4Function(functions, name, args)
+{
+    return (await harness.callTypedFunction(Types.FLOAT4X4, functions, name, args)).subarray(0, 16);
+}
+
 /**
  * Does not return a Promise. To observe the results of a call, 
  * call 'getArrayBuffer' on the Data object retaining your output buffer.

Modified: trunk/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt (247129 => 247130)


--- trunk/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt	2019-07-04 01:29:55 UTC (rev 247129)
+++ trunk/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt	2019-07-04 01:30:15 UTC (rev 247130)
@@ -25,4 +25,9 @@
 PASS Upload and calculate a result from varied argument types. 
 PASS Store into a float4[]. 
 PASS Upload a int[] and store into a int[]. 
+PASS Upload a float4x4[] and store into a float4x4[]. 
+PASS Return an expected float4x4 value. 
+PASS Return an expected float4x4 value. 
+PASS Return an expected float4x4 value. 
+PASS Return an expected float4x4 value. 
 

Modified: trunk/LayoutTests/webgpu/whlsl-test-harness-test.html (247129 => 247130)


--- trunk/LayoutTests/webgpu/whlsl-test-harness-test.html	2019-07-04 01:29:55 UTC (rev 247129)
+++ trunk/LayoutTests/webgpu/whlsl-test-harness-test.html	2019-07-04 01:30:15 UTC (rev 247130)
@@ -27,17 +27,35 @@
     "float": makeFloat
 };
 
+const arrayTypeLengths = {
+    "float4": 4,
+    "float4x4": 16
+};
+
+const arrayFuncs = {
+    "float4": callFloat4Function,
+    "float4x4": callFloat4x4Function,
+};
+
+const arrayArgMakers = {
+    "float4": makeFloat4,
+    "float4x4": makeFloat4x4
+};
+
+const float4x4expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+const float4expected = float4x4expected.slice(0, 4);
+
 let whlslTests = {};
 
 whlslTests.literals = () => {
     checkBools("Return a literal of type bool.", "return true;");
-    checkFloat4s("return float4(0, 1, 2, 3);");
+    checkArrays("float4", "return float4(0, 1, 2, 3);", [], float4expected);
     checkNumericScalars("return 42;", [], 42);
 };
 
 whlslTests.singleArgument = () => {
     checkBools("Upload and return a bool value.", "return in0;", [true]);
-    checkFloat4s("return in0;", [[0, 1, 2, 3]]);
+    checkArrays("float4", "return in0;", [float4expected], float4expected);
     checkNumericScalars("return in0;", [42], 42);
 };
 
@@ -49,8 +67,8 @@
     let body = "return float4(in0.x, in1.y, in2.z, in3.w);"
     let args = [];
     for (let i = 0; i < 4; ++i)
-        args.push([0, 1, 2, 3]);
-    checkFloat4s(body, args, [0, 1, 2, 3]);
+        args.push(float4expected);
+    checkArrays("float4", body, args, float4expected);
 
     body = `return in0 + in1 + in2 + in3 + in4 + in5 + in6 + in7;`;
     checkNumericScalars(body, [0, 1, 2, 3, 4, 5, 6, 7], 28);
@@ -58,7 +76,7 @@
 
 whlslTests.buffersWithOneValue = () => {
     const body = `return in0[0];`
-    checkFloat4s(body, [[[0, 1, 2, 3]]]);
+    checkArrays("float4", body, [[float4expected]], float4expected);
     checkNumericScalars(body, [[42]], 42);
 };
 
@@ -70,8 +88,7 @@
     float w = in0[0].w + in0[1].w + in0[2].w + in1.w + in2[0].w;
 
     return float4(x, y, z, w);`;
-    const vector = [0, 1, 2, 3];
-    checkFloat4s(body, [[vector, vector, vector], vector, [vector]], [0, 5, 10, 15]);
+    checkArrays("float4", body, [[float4expected, float4expected, float4expected], float4expected, [float4expected]], [0, 5, 10, 15]);
 
     body = `return in0[0] + in0[1] + in0[2] + in1 + in2[0];`;
     checkNumericScalars(body, [[0, 1, 2], 3, [4]], 10);
@@ -127,6 +144,38 @@
     }, "Upload a int[] and store into a int[].");
 };
 
+whlslTests.float4x4tests = () => {
+    const src = "" test(device float4x4[] in, device float4x4[] out) {
+        for (uint i = 0; i < 4; i = i + 1)
+            out[i] = in[i];
+    }`;
+    const input = makeFloat4x4([float4x4expected, float4x4expected, float4x4expected, float4x4expected]);
+    const output = makeFloat4x4(new Array(64).fill(0));
+    callVoidFunction(src, "test", [input, output]);
+
+    webGPUPromiseTest(() => {
+        return output.getArrayBuffer().then(arrayBuffer => {
+            const result = new Float32Array(arrayBuffer);
+            for (let i = 0; i < 4; ++i) {
+                for (let j = 0; j < 16; ++j)
+                    assert_approx_equals(result[i * 16 + j], float4x4expected[j], epsilon, "Test stored expected values.");
+            }
+        });
+    }, "Upload a float4x4[] and store into a float4x4[].");
+
+    checkArrays("float4x4", "return float4x4(float4(0, 1, 2, 3), float4(4, 5, 6, 7), float4(8, 9, 10, 11), float4(12, 13, 14, 15));", [], float4x4expected);
+    checkArrays("float4x4", "return in0;", [float4x4expected], float4x4expected);
+    let multiple4x4args = [];
+    for (let i = 0; i < 16; ++i) {
+        const arg = new Array(16);
+        arg.fill(0);
+        arg[i] = i;
+        multiple4x4args.push(arg);
+    }
+    checkArrays("float4x4", "return in0 + in1 + in2 + in3 + in4 + in5 + in6 + in7 + in8 + in9 + in10 + in11 + in12 + in13 + in14 + in15;", multiple4x4args, float4x4expected);
+    checkArrays("float4x4", "return in0[0];", [[float4x4expected]], float4x4expected);
+};
+
 window.addEventListener("load", () => {
     try {
         for (const name in whlslTests) {
@@ -175,26 +224,26 @@
     }, msg);
 };
 
-const checkFloat4s = (body, argValues = [], expected = [0, 1, 2, 3]) => {
+const checkArrays = (type, body, argValues = [], expected) => {
     let inputArgs = [];
     let values = [];
     for (let i = 0; i < argValues.length; ++i) {
         // Support arrays of float4, including one with a single float4.
         const totalLength = argValues[i].flat().length;
-        const isBuffer = argValues[i].length === 1 || totalLength > 4;
-        inputArgs.push(`${isBuffer ? "device " : ""}float4${isBuffer ? "[]" : ""} in${i}`);
-        values.push(makeFloat4(argValues[i]));
+        const isBuffer = argValues[i].length === 1 || totalLength > arrayTypeLengths[type];
+        inputArgs.push(`${isBuffer ? "device " : ""}${type}${isBuffer ? "[]" : ""} in${i}`);
+        values.push(arrayArgMakers[type](argValues[i]));
     }
 
-    const src = "" float4Test(${inputArgs.join(", ")}) { ${body} }
+    const src = "" ${type}Test(${inputArgs.join(", ")}) { ${body} }
     `;
 
     webGPUPromiseTest(async () => {
-        return callFloat4Function(src, "float4Test", values).then(result => {
-            for (let i = 0; i < 4; ++i)
+        return arrayFuncs[type](src, `${type}Test`, values).then(result => {
+            for (let i = 0; i < arrayTypeLengths[type]; ++i)
                 assert_approx_equals(result[i], expected[i], epsilon, "Test returned expected value.");
         });
-    }, "Return an expected float4 value.");
+    }, `Return an expected ${type} value.`);
 }
 
 const appendScalarFunctionToSource = (src, type, body, argValues) => {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to