WebKit Bugzilla
Attachment 373445 Details for
Bug 199484
: [WHLSL] Support float4x4 in test harness
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-199484-20190703174446.patch (text/plain), 11.80 KB, created by
Justin Fan
on 2019-07-03 17:44:46 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Justin Fan
Created:
2019-07-03 17:44:46 PDT
Size:
11.80 KB
patch
obsolete
>Subversion Revision: 247115 >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 3a982f8b4247f4c10c0468e16ad1499c57613d07..489e21b10c6ab36f5a0527300653865797087ba7 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,27 @@ >+2019-07-03 Justin Fan <justin_fan@apple.com> >+ >+ [WHLSL] Support float4x4 in test harness >+ https://bugs.webkit.org/show_bug.cgi?id=199484 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ 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-02 Myles C. Maxfield <mmaxfield@apple.com> > > [WHLSL] Standard library is too big to directly include in WebCore >diff --git a/LayoutTests/webgpu/js/whlsl-test-harness.js b/LayoutTests/webgpu/js/whlsl-test-harness.js >index cfa4c35d0ccae37f884b155356244e33d91364f9..482595c30e13439522eb7db844f10c45fb7e6ad7 100644 >--- a/LayoutTests/webgpu/js/whlsl-test-harness.js >+++ b/LayoutTests/webgpu/js/whlsl-test-harness.js >@@ -9,16 +9,18 @@ const Types = Object.freeze({ > 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: >- return true; >- default: >+ case Types.FLOAT4X4: > return false; >+ default: >+ return true; > } > } > >@@ -37,6 +39,7 @@ function convertTypeToArrayType(isWHLSL, type) > return Uint32Array; > case Types.FLOAT: > case Types.FLOAT4: >+ case Types.FLOAT4X4: > return Float32Array; > default: > throw new Error("Invalid TYPE provided!"); >@@ -58,6 +61,8 @@ function convertTypeToWHLSLType(type) > return "float"; > case Types.FLOAT4: > return "float4"; >+ case Types.FLOAT4X4: >+ return "float4x4"; > default: > throw new Error("Invalid TYPE provided!"); > } >@@ -107,7 +112,7 @@ class Data { > // 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]; >@@ -433,14 +438,34 @@ function makeFloat(values) > * A single 4-element array of floats will be treated as a single float4 argument in the shader. > */ > 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 @@ async function callFloat4Function(functions, name, args) > 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. >diff --git a/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt b/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt >index 26b2bd85dc78bba844f0069978cbea3a1b1f9038..a07577d504d96d77dbc56231449161e052e15c60 100644 >--- a/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt >+++ b/LayoutTests/webgpu/whlsl-test-harness-test-expected.txt >@@ -25,4 +25,9 @@ PASS Return an expected float value. > 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. > >diff --git a/LayoutTests/webgpu/whlsl-test-harness-test.html b/LayoutTests/webgpu/whlsl-test-harness-test.html >index 6128b35c690f472a00eeb40702b3bdb398d18b02..7c622b66bbe286205c050fd0dc94f51a3fde8590 100644 >--- a/LayoutTests/webgpu/whlsl-test-harness-test.html >+++ b/LayoutTests/webgpu/whlsl-test-harness-test.html >@@ -27,17 +27,35 @@ const scalarArgMakers = { > "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 @@ whlslTests.manyArguments = () => { > 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.manyArguments = () => { > > 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 @@ whlslTests.multipleBufferArguments = () => { > 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 @@ whlslTests.bufferStores = () => { > }, "Upload a int[] and store into a int[]."); > }; > >+whlslTests.float4x4tests = () => { >+ const src = `void 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 @@ const checkBools = (msg = "Return an expected bool value.", body, argValues = [] > }, 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 = `float4 float4Test(${inputArgs.join(", ")}) { ${body} } >+ const src = `${type} ${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) => {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199484
: 373445