diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 9476d8431f41..6c9518de081e 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,107 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "38b261fa", - "webgpu/shader/execution/binary/af_logical.bin": "a483b968", - "webgpu/shader/execution/binary/af_division.bin": "ec39b0da", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "ca1373a8", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "406d99af", - "webgpu/shader/execution/binary/af_multiplication.bin": "2eb6d50d", - "webgpu/shader/execution/binary/af_remainder.bin": "e2b6b21", - "webgpu/shader/execution/binary/af_subtraction.bin": "84794350", - "webgpu/shader/execution/binary/f16_addition.bin": "19e8823d", - "webgpu/shader/execution/binary/f16_logical.bin": "b89ca9b9", - "webgpu/shader/execution/binary/f16_division.bin": "6dc4b748", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "7533842", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "2d799920", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "44e3b295", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "412f0911", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "a231201b", - "webgpu/shader/execution/binary/f16_multiplication.bin": "94b11030", - "webgpu/shader/execution/binary/f16_remainder.bin": "de68a200", - "webgpu/shader/execution/binary/f16_subtraction.bin": "f308327a", - "webgpu/shader/execution/binary/f32_addition.bin": "c87c8c08", - "webgpu/shader/execution/binary/f32_logical.bin": "c7370c09", - "webgpu/shader/execution/binary/f32_division.bin": "34ce65ae", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "f3808d0c", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "e33e7fe5", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "41091ebf", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "37ccb101", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "4d67866", - "webgpu/shader/execution/binary/f32_multiplication.bin": "5d85a36c", - "webgpu/shader/execution/binary/f32_remainder.bin": "62f591b2", - "webgpu/shader/execution/binary/f32_subtraction.bin": "60fc275a", - "webgpu/shader/execution/binary/i32_arithmetic.bin": "a0b0a016", - "webgpu/shader/execution/binary/i32_comparison.bin": "f3d9b3f9", - "webgpu/shader/execution/binary/u32_arithmetic.bin": "16e32fd", - "webgpu/shader/execution/binary/u32_comparison.bin": "da33cc5d", - "webgpu/shader/execution/abs.bin": "1ead834c", - "webgpu/shader/execution/acos.bin": "e25802ba", - "webgpu/shader/execution/acosh.bin": "2321726f", - "webgpu/shader/execution/asin.bin": "d554a73b", - "webgpu/shader/execution/asinh.bin": "d2bdb21b", - "webgpu/shader/execution/atan.bin": "eb6476f3", - "webgpu/shader/execution/atan2.bin": "cf15e7fa", - "webgpu/shader/execution/atanh.bin": "6c57cc3", - "webgpu/shader/execution/bitcast.bin": "a25e9714", - "webgpu/shader/execution/ceil.bin": "8d120ea3", - "webgpu/shader/execution/clamp.bin": "a762ef58", - "webgpu/shader/execution/cos.bin": "a859da89", - "webgpu/shader/execution/cosh.bin": "86abdd85", - "webgpu/shader/execution/cross.bin": "e4556729", - "webgpu/shader/execution/degrees.bin": "1fa19a41", - "webgpu/shader/execution/determinant.bin": "108c3d65", - "webgpu/shader/execution/distance.bin": "77a1baa6", - "webgpu/shader/execution/dot.bin": "d4ac2e8a", - "webgpu/shader/execution/exp.bin": "15539afd", - "webgpu/shader/execution/exp2.bin": "7f6a8523", - "webgpu/shader/execution/faceForward.bin": "e7b35f43", - "webgpu/shader/execution/floor.bin": "b26656ca", - "webgpu/shader/execution/fma.bin": "5a70c683", - "webgpu/shader/execution/fract.bin": "23c0d5ec", - "webgpu/shader/execution/frexp.bin": "d28e66be", - "webgpu/shader/execution/inverseSqrt.bin": "9f297854", - "webgpu/shader/execution/ldexp.bin": "638db0c7", - "webgpu/shader/execution/length.bin": "7d237c62", - "webgpu/shader/execution/log.bin": "70720bf0", - "webgpu/shader/execution/log2.bin": "93a309be", - "webgpu/shader/execution/max.bin": "36eb4779", - "webgpu/shader/execution/min.bin": "ca772bf1", - "webgpu/shader/execution/mix.bin": "ecbf61ae", - "webgpu/shader/execution/modf.bin": "6ddea900", - "webgpu/shader/execution/normalize.bin": "d3e47c61", - "webgpu/shader/execution/pack2x16float.bin": "e6859c1a", - "webgpu/shader/execution/pow.bin": "a58be71c", - "webgpu/shader/execution/quantizeToF16.bin": "eca85bca", - "webgpu/shader/execution/radians.bin": "a216c9aa", - "webgpu/shader/execution/reflect.bin": "ebce9830", - "webgpu/shader/execution/refract.bin": "59d1e5d6", - "webgpu/shader/execution/round.bin": "9389a090", - "webgpu/shader/execution/saturate.bin": "7ca4b681", - "webgpu/shader/execution/sign.bin": "1f4eeb34", - "webgpu/shader/execution/sin.bin": "a1e234b4", - "webgpu/shader/execution/sinh.bin": "1a62054b", - "webgpu/shader/execution/smoothstep.bin": "d5824fd6", - "webgpu/shader/execution/sqrt.bin": "66f21d02", - "webgpu/shader/execution/step.bin": "310cb6c7", - "webgpu/shader/execution/tan.bin": "1e26f533", - "webgpu/shader/execution/tanh.bin": "4c546d1c", - "webgpu/shader/execution/transpose.bin": "7bef2494", - "webgpu/shader/execution/trunc.bin": "e72535eb", - "webgpu/shader/execution/unpack2x16float.bin": "593d88c6", - "webgpu/shader/execution/unpack2x16snorm.bin": "9ebd3e40", - "webgpu/shader/execution/unpack2x16unorm.bin": "83a36fa9", - "webgpu/shader/execution/unpack4x8snorm.bin": "41b12606", - "webgpu/shader/execution/unpack4x8unorm.bin": "96f1850b", - "webgpu/shader/execution/unary/af_arithmetic.bin": "6fa1d84a", - "webgpu/shader/execution/unary/af_assignment.bin": "98c8f82a", - "webgpu/shader/execution/unary/bool_conversion.bin": "dd71f171", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "2f2d38fc", - "webgpu/shader/execution/unary/f16_conversion.bin": "70c94538", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "db90c01c", - "webgpu/shader/execution/unary/f32_conversion.bin": "81912140", - "webgpu/shader/execution/unary/i32_arithmetic.bin": "c69716e2", - "webgpu/shader/execution/unary/i32_conversion.bin": "83218e69", - "webgpu/shader/execution/unary/u32_conversion.bin": "8f5bad00", - "webgpu/shader/execution/unary/ai_assignment.bin": "c7e6ac33", - "webgpu/shader/execution/binary/ai_arithmetic.bin": "81c11ec2", - "webgpu/shader/execution/unary/ai_arithmetic.bin": "3d27dc97" + "webgpu/shader/execution/binary/af_addition.bin": "25dcfcce", + "webgpu/shader/execution/binary/af_logical.bin": "409d37cf", + "webgpu/shader/execution/binary/af_division.bin": "bfcb23bd", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "cefea21a", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "624d816d", + "webgpu/shader/execution/binary/af_multiplication.bin": "34077746", + "webgpu/shader/execution/binary/af_remainder.bin": "9eddf765", + "webgpu/shader/execution/binary/af_subtraction.bin": "629bbf4", + "webgpu/shader/execution/binary/f16_addition.bin": "e3ff1263", + "webgpu/shader/execution/binary/f16_logical.bin": "99c0a0ed", + "webgpu/shader/execution/binary/f16_division.bin": "c0f3376", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "3054016e", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "9cb6bbb9", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "82f32c1d", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "29e9e0c7", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "109260c1", + "webgpu/shader/execution/binary/f16_multiplication.bin": "39287c38", + "webgpu/shader/execution/binary/f16_remainder.bin": "98b48517", + "webgpu/shader/execution/binary/f16_subtraction.bin": "a4975dc4", + "webgpu/shader/execution/binary/f32_addition.bin": "b0e6fddd", + "webgpu/shader/execution/binary/f32_logical.bin": "71a0f0be", + "webgpu/shader/execution/binary/f32_division.bin": "29a37cf9", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "76e48aa9", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "37f3a30b", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "f00c4cd8", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "25553482", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "26750bd3", + "webgpu/shader/execution/binary/f32_multiplication.bin": "68a7516b", + "webgpu/shader/execution/binary/f32_remainder.bin": "fb22b625", + "webgpu/shader/execution/binary/f32_subtraction.bin": "2e26b05f", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "9256ccab", + "webgpu/shader/execution/binary/i32_comparison.bin": "c813abfa", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "498f877e", + "webgpu/shader/execution/binary/u32_comparison.bin": "d69e1738", + "webgpu/shader/execution/abs.bin": "a6b6fed1", + "webgpu/shader/execution/acos.bin": "2a8f33b0", + "webgpu/shader/execution/acosh.bin": "3b39f532", + "webgpu/shader/execution/asin.bin": "94c67af3", + "webgpu/shader/execution/asinh.bin": "34c8547a", + "webgpu/shader/execution/atan.bin": "c5f98dae", + "webgpu/shader/execution/atan2.bin": "5c666ada", + "webgpu/shader/execution/atanh.bin": "5efbba8b", + "webgpu/shader/execution/bitcast.bin": "e90abd26", + "webgpu/shader/execution/ceil.bin": "fe43b603", + "webgpu/shader/execution/clamp.bin": "f4ec869a", + "webgpu/shader/execution/cos.bin": "78f30673", + "webgpu/shader/execution/cosh.bin": "15c18b89", + "webgpu/shader/execution/cross.bin": "72823897", + "webgpu/shader/execution/degrees.bin": "3b06fea4", + "webgpu/shader/execution/determinant.bin": "f0f66549", + "webgpu/shader/execution/distance.bin": "593c41fb", + "webgpu/shader/execution/dot.bin": "3eee146b", + "webgpu/shader/execution/exp.bin": "7f926769", + "webgpu/shader/execution/exp2.bin": "715c82a", + "webgpu/shader/execution/faceForward.bin": "8a365384", + "webgpu/shader/execution/floor.bin": "7b9a6254", + "webgpu/shader/execution/fma.bin": "88549fc7", + "webgpu/shader/execution/fract.bin": "e4eff2f9", + "webgpu/shader/execution/frexp.bin": "18a53421", + "webgpu/shader/execution/inverseSqrt.bin": "71016a37", + "webgpu/shader/execution/ldexp.bin": "450c6068", + "webgpu/shader/execution/length.bin": "62190368", + "webgpu/shader/execution/log.bin": "c4b1985b", + "webgpu/shader/execution/log2.bin": "28ccd982", + "webgpu/shader/execution/max.bin": "ba573f18", + "webgpu/shader/execution/min.bin": "5a834580", + "webgpu/shader/execution/mix.bin": "bf942d40", + "webgpu/shader/execution/modf.bin": "a8de3f36", + "webgpu/shader/execution/normalize.bin": "4bf84190", + "webgpu/shader/execution/pack2x16float.bin": "cc42ef45", + "webgpu/shader/execution/pow.bin": "6e8d08d1", + "webgpu/shader/execution/quantizeToF16.bin": "8c615e93", + "webgpu/shader/execution/radians.bin": "624ff571", + "webgpu/shader/execution/reflect.bin": "d0d624ae", + "webgpu/shader/execution/refract.bin": "3dd68359", + "webgpu/shader/execution/round.bin": "502c36a8", + "webgpu/shader/execution/saturate.bin": "be4cf88f", + "webgpu/shader/execution/sign.bin": "91310555", + "webgpu/shader/execution/sin.bin": "441d6be3", + "webgpu/shader/execution/sinh.bin": "4ebaa2e7", + "webgpu/shader/execution/smoothstep.bin": "6298e644", + "webgpu/shader/execution/sqrt.bin": "3cf64df1", + "webgpu/shader/execution/step.bin": "90148c99", + "webgpu/shader/execution/tan.bin": "e753749c", + "webgpu/shader/execution/tanh.bin": "62c99641", + "webgpu/shader/execution/transpose.bin": "2a4448c6", + "webgpu/shader/execution/trunc.bin": "ed9a0d22", + "webgpu/shader/execution/unpack2x16float.bin": "e81297f7", + "webgpu/shader/execution/unpack2x16snorm.bin": "513f9a8b", + "webgpu/shader/execution/unpack2x16unorm.bin": "8b56d0ce", + "webgpu/shader/execution/unpack4x8snorm.bin": "51af8a63", + "webgpu/shader/execution/unpack4x8unorm.bin": "302cf4a6", + "webgpu/shader/execution/unary/af_arithmetic.bin": "cd4618d", + "webgpu/shader/execution/unary/af_assignment.bin": "7d5de0f1", + "webgpu/shader/execution/unary/bool_conversion.bin": "401fb8c5", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "ad86d013", + "webgpu/shader/execution/unary/f16_conversion.bin": "86e35a85", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "fe97afd1", + "webgpu/shader/execution/unary/f32_conversion.bin": "97730c3c", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "69f783bb", + "webgpu/shader/execution/unary/i32_conversion.bin": "4fec061e", + "webgpu/shader/execution/unary/u32_conversion.bin": "1a298dea", + "webgpu/shader/execution/unary/ai_assignment.bin": "1c2edca2", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "657f2fb7", + "webgpu/shader/execution/unary/ai_arithmetic.bin": "216769d9", + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "544f4363", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "14212e77", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "57f19c15" } \ No newline at end of file diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin new file mode 100644 index 000000000000..5f8636b77c7d Binary files /dev/null and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin new file mode 100644 index 000000000000..a8d35f964d4e Binary files /dev/null and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin differ diff --git a/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin new file mode 100644 index 000000000000..0a61c01c1a46 Binary files /dev/null and b/src/resources/cache/webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin differ diff --git a/src/unittests/conversion.spec.ts b/src/unittests/conversion.spec.ts index 8606aa871794..e144f39288a2 100644 --- a/src/unittests/conversion.spec.ts +++ b/src/unittests/conversion.spec.ts @@ -18,7 +18,7 @@ import { i32, kFloat16Format, kFloat32Format, - Matrix, + MatrixValue, numbersApproximatelyEqual, pack2x16float, pack2x16snorm, @@ -26,14 +26,14 @@ import { pack4x8snorm, pack4x8unorm, packRGB9E5UFloat, - Scalar, + ScalarValue, toMatrix, u32, unpackRGB9E5UFloat, vec2, vec3, vec4, - Vector, + VectorValue, } from '../webgpu/util/conversion.js'; import { UnitTest } from './unit_test.js'; @@ -191,7 +191,7 @@ g.test('floatBitsToULPFromZero,32').fn(t => { }); g.test('scalarWGSL').fn(t => { - const cases: Array<[Scalar, string]> = [ + const cases: Array<[ScalarValue, string]> = [ [f32(0.0), '0.0f'], // The number -0.0 can be remapped to 0.0 when stored in a Scalar // object. It is not possible to guarantee that '-0.0f' will @@ -227,7 +227,7 @@ expect: ${expect}` }); g.test('vectorWGSL').fn(t => { - const cases: Array<[Vector, string]> = [ + const cases: Array<[VectorValue, string]> = [ [vec2(f32(42.0), f32(24.0)), 'vec2(42.0f, 24.0f)'], [vec2(f16Bits(0x5140), f16Bits(0x4e00)), 'vec2(42.0h, 24.0h)'], [vec2(u32(42), u32(24)), 'vec2(42u, 24u)'], @@ -261,7 +261,7 @@ expect: ${expect}` }); g.test('matrixWGSL').fn(t => { - const cases: Array<[Matrix, string]> = [ + const cases: Array<[MatrixValue, string]> = [ [ toMatrix( [ @@ -391,7 +391,7 @@ g.test('constructorMatrix') return [...Array(rows).keys()].map(r => scalar_builder(c * cols + r)); }); - const got = new Matrix(elements); + const got = new MatrixValue(elements); const got_type = got.type; t.expect( got_type.cols === cols, diff --git a/src/unittests/floating_point.spec.ts b/src/unittests/floating_point.spec.ts index 23bfaafc2268..ad27c1d711d8 100644 --- a/src/unittests/floating_point.spec.ts +++ b/src/unittests/floating_point.spec.ts @@ -7193,7 +7193,7 @@ g.test('subtractionMatrixMatrixInterval') g.test('multiplicationMatrixMatrixInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly @@ -7768,12 +7768,26 @@ const kMultiplicationMatrixScalarIntervalCases = { ], }, ] as MatrixScalarToMatrixCase[], + abstract: [ + // From https://github.com/gpuweb/cts/issues/3044 + { + matrix: [ + [kValue.f64.negative.min, 0], + [0, 0], + ], + scalar: kValue.f64.negative.subnormal.min, + expected: [ + [[0, reinterpretU64AsF64(0x400ffffffffffffdn)], 0], // [[0, 3.9999995...], 0], + [0, 0], + ], + }, + ] as MatrixScalarToMatrixCase[], } as const; g.test('multiplicationMatrixScalarInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .expandWithParams(p => { const trait = FP[p.trait]; @@ -7945,7 +7959,7 @@ interface MatrixVectorToVectorCase { g.test('multiplicationMatrixVectorInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly @@ -8062,7 +8076,7 @@ interface VectorMatrixToVectorCase { g.test('multiplicationVectorMatrixInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .combineWithParams([ // Only testing that different shapes of matrices are handled correctly @@ -8070,8 +8084,8 @@ g.test('multiplicationVectorMatrixInterval') // multiplicationVectorMatrixInterval uses DotIntervalOp for calculating // intervals, so the testing for dotInterval covers the actual interval // calculations. - // Keep all expected result integer no larger than 2047 to ensure that all result is exactly - // represeantable in both f32 and f16. + // Keep all expected result integer no larger than 2047 to ensure that + // all result is exactly representable in both f32 and f16. { vector: [1, 2], matrix: [ diff --git a/src/webgpu/api/operation/render_pipeline/sample_mask.spec.ts b/src/webgpu/api/operation/render_pipeline/sample_mask.spec.ts index ca4a2479658e..b28e1b381cad 100644 --- a/src/webgpu/api/operation/render_pipeline/sample_mask.spec.ts +++ b/src/webgpu/api/operation/render_pipeline/sample_mask.spec.ts @@ -21,7 +21,7 @@ import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { assert, range } from '../../../../common/util/util.js'; import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { checkElementsPassPredicate, checkElementsEqual } from '../../../util/check_contents.js'; -import { TypeF32, TypeU32 } from '../../../util/conversion.js'; +import { Type } from '../../../util/conversion.js'; import { TexelView } from '../../../util/texture/texel_view.js'; const kColors = [ @@ -438,7 +438,7 @@ class F extends TextureTestMixin(GPUTest) { fragmentShaderOutputMask: number ) { const buffer = this.copy2DTextureToBufferUsingComputePass( - TypeF32, // correspond to 'rgba8unorm' format + Type.f32, // correspond to 'rgba8unorm' format 4, texture.createView(), sampleCount @@ -464,7 +464,7 @@ class F extends TextureTestMixin(GPUTest) { const buffer = this.copy2DTextureToBufferUsingComputePass( // Use f32 as the scalar type for depth (depth24plus, depth32float) // Use u32 as the scalar type for stencil (stencil8) - aspect === 'depth-only' ? TypeF32 : TypeU32, + aspect === 'depth-only' ? Type.f32 : Type.u32, 1, depthStencilTexture.createView({ aspect }), sampleCount @@ -705,7 +705,7 @@ color' <= color. ); const colorBuffer = t.copy2DTextureToBufferUsingComputePass( - TypeF32, // correspond to 'rgba8unorm' format + Type.f32, // correspond to 'rgba8unorm' format 4, color.createView(), sampleCount @@ -717,7 +717,7 @@ color' <= color. colorResultPromises.push(colorResult); const depthBuffer = t.copy2DTextureToBufferUsingComputePass( - TypeF32, // correspond to 'depth24plus-stencil8' format + Type.f32, // correspond to 'depth24plus-stencil8' format 1, depthStencil.createView({ aspect: 'depth-only' }), sampleCount @@ -729,7 +729,7 @@ color' <= color. depthResultPromises.push(depthResult); const stencilBuffer = t.copy2DTextureToBufferUsingComputePass( - TypeU32, // correspond to 'depth24plus-stencil8' format + Type.u32, // correspond to 'depth24plus-stencil8' format 1, depthStencil.createView({ aspect: 'stencil-only' }), sampleCount diff --git a/src/webgpu/api/operation/rendering/draw.spec.ts b/src/webgpu/api/operation/rendering/draw.spec.ts index 6ed4be08fd24..fc8fdf2224d1 100644 --- a/src/webgpu/api/operation/rendering/draw.spec.ts +++ b/src/webgpu/api/operation/rendering/draw.spec.ts @@ -11,10 +11,10 @@ import { TypedArrayBufferView, TypedArrayBufferViewConstructor, } from '../../../../common/util/util.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { AdapterLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { PerPixelComparison } from '../../../util/texture/texture_ok.js'; -class DrawTest extends TextureTestMixin(GPUTest) { +class DrawTest extends TextureTestMixin(AdapterLimitsGPUTest) { checkTriangleDraw(opts: { firstIndex: number | undefined; count: number; diff --git a/src/webgpu/gpu_test.ts b/src/webgpu/gpu_test.ts index 1f021218d290..a2ae8f1b901f 100644 --- a/src/webgpu/gpu_test.ts +++ b/src/webgpu/gpu_test.ts @@ -93,11 +93,47 @@ export function initUncanonicalizedDeviceDescriptor( } } +/** + * Gets the adapter limits as a standard JavaScript object. + */ +function getAdapterLimitsAsDeviceRequiredLimits(adapter: GPUAdapter) { + const requiredLimits: Record = {}; + const adapterLimits = adapter.limits as unknown as Record; + for (const key in adapter.limits) { + requiredLimits[key] = adapterLimits[key]; + } + return requiredLimits; +} + +/** + * Conditionally applies adapter limits to device descriptor + * but does not overwrite existing requested limits. + */ +function conditionallyApplyAdapterLimitsToDeviceDescriptor( + adapter: GPUAdapter, + useAdapterLimits: boolean, + descriptor: UncanonicalizedDeviceDescriptor | undefined +): UncanonicalizedDeviceDescriptor { + return { + ...(descriptor || {}), + requiredLimits: { + ...(useAdapterLimits && getAdapterLimitsAsDeviceRequiredLimits(adapter)), + ...(descriptor?.requiredLimits || {}), + }, + }; +} + export class GPUTestSubcaseBatchState extends SubcaseBatchState { /** Provider for default device. */ private provider: Promise | undefined; /** Provider for mismatched device. */ private mismatchedProvider: Promise | undefined; + /** True if device should be created with adapter limits */ + private useAdapterLimits = false; + + constructor(recorder: TestCaseRecorder, params: TestParams) { + super(recorder, params); + } override async postInit(): Promise { // Skip all subcases if there's no device. @@ -123,6 +159,14 @@ export class GPUTestSubcaseBatchState extends SubcaseBatchState { return this.provider; } + useAdapterLimitsForDevice() { + assert( + this.provider === undefined, + 'useAdapterLimits must be called before getting the device' + ); + this.useAdapterLimits = true; + } + get isCompatibility() { return globalTestConfig.compatibility; } @@ -140,10 +184,18 @@ export class GPUTestSubcaseBatchState extends SubcaseBatchState { */ selectDeviceOrSkipTestCase(descriptor: DeviceSelectionDescriptor): void { assert(this.provider === undefined, "Can't selectDeviceOrSkipTestCase() multiple times"); - this.provider = devicePool.acquire( - this.recorder, - initUncanonicalizedDeviceDescriptor(descriptor) - ); + this.provider = devicePool + .requestAdapter(this.recorder) + .then(adapter => + devicePool.acquire( + adapter, + conditionallyApplyAdapterLimitsToDeviceDescriptor( + adapter, + this.useAdapterLimits, + initUncanonicalizedDeviceDescriptor(descriptor) + ) + ) + ); // Suppress uncaught promise rejection (we'll catch it later). this.provider.catch(() => {}); } @@ -201,10 +253,18 @@ export class GPUTestSubcaseBatchState extends SubcaseBatchState { "Can't selectMismatchedDeviceOrSkipTestCase() multiple times" ); - this.mismatchedProvider = mismatchedDevicePool.acquire( - this.recorder, - initUncanonicalizedDeviceDescriptor(descriptor) - ); + this.mismatchedProvider = mismatchedDevicePool + .requestAdapter(this.recorder) + .then(adapter => + mismatchedDevicePool.acquire( + adapter, + conditionallyApplyAdapterLimitsToDeviceDescriptor( + adapter, + this.useAdapterLimits, + initUncanonicalizedDeviceDescriptor(descriptor) + ) + ) + ); // Suppress uncaught promise rejection (we'll catch it later). this.mismatchedProvider.catch(() => {}); } @@ -1203,6 +1263,20 @@ export class GPUTest extends GPUTestBase { } } +/** + * A version of GPUTest that requires the adapter limits. + */ +export class AdapterLimitsGPUTest extends GPUTest { + public static override MakeSharedState( + recorder: TestCaseRecorder, + params: TestParams + ): GPUTestSubcaseBatchState { + const state = new GPUTestSubcaseBatchState(recorder, params); + state.useAdapterLimitsForDevice(); + return state; + } +} + /** * Texture expectation mixin can be applied on top of GPUTest to add texture * related expectation helpers. diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index ec5c059d5149..327ba644120d 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -914,7 +914,12 @@ "webgpu:shader,execution,expression,binary,af_division:vector:*": { "subcaseMS": 237.134 }, "webgpu:shader,execution,expression,binary,af_division:vector_scalar:*": { "subcaseMS": 580.000 }, "webgpu:shader,execution,expression,binary,af_matrix_addition:matrix:*": { "subcaseMS": 11169.534 }, + "webgpu:shader,execution,expression,binary,af_matrix_matrix_multiplication:matrix_matrix:*": { "subcaseMS": 0.000 }, + "webgpu:shader,execution,expression,binary,af_matrix_scalar_multiplication:matrix_scalar:*": { "subcaseMS": 0.000 }, + "webgpu:shader,execution,expression,binary,af_matrix_scalar_multiplication:scalar_matrix:*": { "subcaseMS": 0.000 }, "webgpu:shader,execution,expression,binary,af_matrix_subtraction:matrix:*": { "subcaseMS": 14060.956 }, + "webgpu:shader,execution,expression,binary,af_matrix_vector_multiplication:matrix_vector:*": { "subcaseMS": 0.000 }, + "webgpu:shader,execution,expression,binary,af_matrix_vector_multiplication:vector_matrix:*": { "subcaseMS": 0.000 }, "webgpu:shader,execution,expression,binary,af_multiplication:scalar:*": { "subcaseMS": 777.901 }, "webgpu:shader,execution,expression,binary,af_multiplication:scalar_vector:*": { "subcaseMS": 2025.534 }, "webgpu:shader,execution,expression,binary,af_multiplication:vector:*": { "subcaseMS": 710.667 }, @@ -1738,6 +1743,7 @@ "webgpu:shader,execution,shader_io,shared_structs:shared_between_stages:*": { "subcaseMS": 9.601 }, "webgpu:shader,execution,shader_io,shared_structs:shared_with_buffer:*": { "subcaseMS": 20.701 }, "webgpu:shader,execution,shader_io,shared_structs:shared_with_non_entry_point_function:*": { "subcaseMS": 6.801 }, + "webgpu:shader,execution,shader_io,user_io:passthrough:*": { "subcaseMS": 373.385 }, "webgpu:shader,execution,shader_io,workgroup_size:workgroup_size:*": { "subcaseMS": 0.000 }, "webgpu:shader,execution,shadow:builtin:*": { "subcaseMS": 4.700 }, "webgpu:shader,execution,shadow:declaration:*": { "subcaseMS": 9.700 }, @@ -1807,6 +1813,7 @@ "webgpu:shader,validation,expression,binary,bitwise_shift:shift_left_vec_size_mismatch:*": { "subcaseMS": 1.367 }, "webgpu:shader,validation,expression,binary,bitwise_shift:shift_right_concrete:*": { "subcaseMS": 1.237 }, "webgpu:shader,validation,expression,binary,bitwise_shift:shift_right_vec_size_mismatch:*": { "subcaseMS": 1.334 }, + "webgpu:shader,validation,expression,call,builtin,abs:parameters:*": { "subcaseMS": 10.133 }, "webgpu:shader,validation,expression,call,builtin,abs:values:*": { "subcaseMS": 0.391 }, "webgpu:shader,validation,expression,call,builtin,acos:integer_argument:*": { "subcaseMS": 1.512 }, "webgpu:shader,validation,expression,call,builtin,acos:values:*": { "subcaseMS": 0.342 }, @@ -1925,6 +1932,8 @@ "webgpu:shader,validation,expression,unary,address_of_and_indirection:invalid:*": { "subcaseMS": 0.000 }, "webgpu:shader,validation,extension,pointer_composite_access:deref:*": { "subcaseMS": 0.000 }, "webgpu:shader,validation,extension,pointer_composite_access:pointer:*": { "subcaseMS": 0.000 }, + "webgpu:shader,validation,extension,readonly_and_readwrite_storage_textures:textureBarrier:*": { "subcaseMS": 1.141 }, + "webgpu:shader,validation,extension,readonly_and_readwrite_storage_textures:var_decl:*": { "subcaseMS": 42.299 }, "webgpu:shader,validation,functions,alias_analysis:aliasing_inside_function:*": { "subcaseMS": 1.200 }, "webgpu:shader,validation,functions,alias_analysis:member_accessors:*": { "subcaseMS": 1.656 }, "webgpu:shader,validation,functions,alias_analysis:one_atomic_pointer_one_module_scope:*": { "subcaseMS": 0.000 }, @@ -1979,6 +1988,7 @@ "webgpu:shader,validation,parse,diagnostic:conflicting_attribute_different_location:*": { "subcaseMS": 2.257 }, "webgpu:shader,validation,parse,diagnostic:conflicting_attribute_same_location:*": { "subcaseMS": 1.400 }, "webgpu:shader,validation,parse,diagnostic:conflicting_directive:*": { "subcaseMS": 1.244 }, + "webgpu:shader,validation,parse,diagnostic:diagnostic_scoping:*": { "subcaseMS": 1.244 }, "webgpu:shader,validation,parse,diagnostic:invalid_locations:*": { "subcaseMS": 1.930 }, "webgpu:shader,validation,parse,diagnostic:invalid_severity:*": { "subcaseMS": 1.361 }, "webgpu:shader,validation,parse,diagnostic:valid_locations:*": { "subcaseMS": 1.368 }, @@ -2200,6 +2210,7 @@ "webgpu:web_platform,external_texture,video:importExternalTexture,compute:*": { "subcaseMS": 36.270 }, "webgpu:web_platform,external_texture,video:importExternalTexture,sample:*": { "subcaseMS": 34.968 }, "webgpu:web_platform,external_texture,video:importExternalTexture,sampleWithVideoFrameWithVisibleRectParam:*": { "subcaseMS": 29.160 }, + "webgpu:web_platform,external_texture,video:importExternalTexture,sample_non_YUV_video_frame:*": { "subcaseMS": 36.270 }, "webgpu:web_platform,worker,worker:dedicated_worker:*": { "subcaseMS": 245.901 }, "webgpu:web_platform,worker,worker:shared_worker:*": { "subcaseMS": 26.801 }, "_end": "" diff --git a/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts index 3b14897c2227..52a07ff328f8 100644 --- a/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_addition.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for non-matrix AbstractFloat addition expression +Execution Tests for non-matrix abstract-float addition expression `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_addition.cache.js'; @@ -26,8 +26,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('+'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -49,8 +49,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('+'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('+'), - [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(dim, TypeAbstractFloat), + [Type.vec(dim, Type.abstractFloat), Type.abstractFloat], + Type.vec(dim, Type.abstractFloat), t.params, cases ); @@ -93,8 +93,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('+'), - [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], - TypeVec(dim, TypeAbstractFloat), + [Type.abstractFloat, Type.vec(dim, Type.abstractFloat)], + Type.vec(dim, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_comparison.cache.ts b/src/webgpu/shader/execution/expression/binary/af_comparison.cache.ts index 648ea5c0b0b8..e0002664018a 100644 --- a/src/webgpu/shader/execution/expression/binary/af_comparison.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/af_comparison.cache.ts @@ -1,5 +1,5 @@ import { anyOf } from '../../../../util/compare.js'; -import { abstractFloat, bool, Scalar } from '../../../../util/conversion.js'; +import { abstractFloat, bool, ScalarValue } from '../../../../util/conversion.js'; import { flushSubnormalNumberF64, vectorF64Range } from '../../../../util/math.js'; import { Case } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; @@ -11,7 +11,7 @@ import { makeCaseCache } from '../case_cache.js'; function makeCase( lhs: number, rhs: number, - truthFunc: (lhs: Scalar, rhs: Scalar) => boolean + truthFunc: (lhs: ScalarValue, rhs: ScalarValue) => boolean ): Case { // Subnormal float values may be flushed at any time. // https://www.w3.org/TR/WGSL/#floating-point-evaluation @@ -19,7 +19,7 @@ function makeCase( const af_rhs = abstractFloat(rhs); const lhs_options = new Set([af_lhs, abstractFloat(flushSubnormalNumberF64(lhs))]); const rhs_options = new Set([af_rhs, abstractFloat(flushSubnormalNumberF64(rhs))]); - const expected: Array = []; + const expected: Array = []; lhs_options.forEach(l => { rhs_options.forEach(r => { const result = bool(truthFunc(l, r)); @@ -34,7 +34,7 @@ function makeCase( export const d = makeCaseCache('binary/af_logical', { equals: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) === (rhs.value as number); }; @@ -43,7 +43,7 @@ export const d = makeCaseCache('binary/af_logical', { }); }, not_equals: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) !== (rhs.value as number); }; @@ -52,7 +52,7 @@ export const d = makeCaseCache('binary/af_logical', { }); }, less_than: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) < (rhs.value as number); }; @@ -61,7 +61,7 @@ export const d = makeCaseCache('binary/af_logical', { }); }, less_equals: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) <= (rhs.value as number); }; @@ -70,7 +70,7 @@ export const d = makeCaseCache('binary/af_logical', { }); }, greater_than: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) > (rhs.value as number); }; @@ -79,7 +79,7 @@ export const d = makeCaseCache('binary/af_logical', { }); }, greater_equals: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) >= (rhs.value as number); }; diff --git a/src/webgpu/shader/execution/expression/binary/af_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/af_comparison.spec.ts index cc03ee4367f2..3941e1253969 100644 --- a/src/webgpu/shader/execution/expression/binary/af_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_comparison.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for the AbstractFloat comparison operations +Execution Tests for the abstract-float comparison operations `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeBool } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { d } from './af_comparison.cache.js'; @@ -27,7 +27,14 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('equals'); - await run(t, binary('=='), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run( + t, + binary('=='), + [Type.abstractFloat, Type.abstractFloat], + Type.bool, + t.params, + cases + ); }); g.test('not_equals') @@ -45,7 +52,14 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('not_equals'); - await run(t, binary('!='), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run( + t, + binary('!='), + [Type.abstractFloat, Type.abstractFloat], + Type.bool, + t.params, + cases + ); }); g.test('less_than') @@ -63,7 +77,7 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('less_than'); - await run(t, binary('<'), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.abstractFloat, Type.abstractFloat], Type.bool, t.params, cases); }); g.test('less_equals') @@ -81,7 +95,14 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('less_equals'); - await run(t, binary('<='), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run( + t, + binary('<='), + [Type.abstractFloat, Type.abstractFloat], + Type.bool, + t.params, + cases + ); }); g.test('greater_than') @@ -99,7 +120,7 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('greater_than'); - await run(t, binary('>'), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.abstractFloat, Type.abstractFloat], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -117,5 +138,12 @@ Accuracy: Correct result ) .fn(async t => { const cases = await d.get('greater_equals'); - await run(t, binary('>='), [TypeAbstractFloat, TypeAbstractFloat], TypeBool, t.params, cases); + await run( + t, + binary('>='), + [Type.abstractFloat, Type.abstractFloat], + Type.bool, + t.params, + cases + ); }); diff --git a/src/webgpu/shader/execution/expression/binary/af_division.spec.ts b/src/webgpu/shader/execution/expression/binary/af_division.spec.ts index 5080e62264d2..0ebe30b6ccc9 100644 --- a/src/webgpu/shader/execution/expression/binary/af_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_division.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for non-matrix AbstractFloat division expression +Execution Tests for non-matrix abstract-float division expression `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_division.cache.js'; @@ -26,8 +26,8 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] await run( t, abstractFloatBinary('/'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -49,8 +49,8 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] await run( t, abstractFloatBinary('/'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('/'), - [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(dim, TypeAbstractFloat), + [Type.vec(dim, Type.abstractFloat), Type.abstractFloat], + Type.vec(dim, Type.abstractFloat), t.params, cases ); @@ -93,8 +93,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('/'), - [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], - TypeVec(dim, TypeAbstractFloat), + [Type.abstractFloat, Type.vec(dim, Type.abstractFloat)], + Type.vec(dim, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts index 7f6019f53127..49c746c53e74 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_addition.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for matrix AbstractFloat addition expressions +Execution Tests for matrix abstract-float addition expressions `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_matrix_addition.cache.js'; @@ -33,8 +33,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('+'), - [TypeMat(cols, rows, TypeAbstractFloat), TypeMat(cols, rows, TypeAbstractFloat)], - TypeMat(cols, rows, TypeAbstractFloat), + [Type.mat(cols, rows, Type.abstractFloat), Type.mat(cols, rows, Type.abstractFloat)], + Type.mat(cols, rows, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts new file mode 100644 index 000000000000..c7540083d6ff --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.cache.ts @@ -0,0 +1,28 @@ +import { FP } from '../../../../util/floating_point.js'; +import { sparseMatrixF64Range } from '../../../../util/math.js'; +import { selectNCases } from '../case.js'; +import { makeCaseCache } from '../case_cache.js'; + +// Cases: matKxR_matCxK +const mat_mat_cases = ([2, 3, 4] as const) + .flatMap(k => + ([2, 3, 4] as const).flatMap(cols => + ([2, 3, 4] as const).map(rows => ({ + [`mat${k}x${rows}_mat${cols}x${k}`]: () => { + return selectNCases( + 'binary/af_matrix_matrix_multiplication', + 50, + FP.abstract.generateMatrixPairToMatrixCases( + sparseMatrixF64Range(k, rows), + sparseMatrixF64Range(cols, k), + 'finite', + FP.abstract.multiplicationMatrixMatrixInterval + ) + ); + }, + })) + ) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('binary/af_matrix_matrix_multiplication', mat_mat_cases); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.spec.ts new file mode 100644 index 000000000000..a1aa005d341c --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_matrix_multiplication.spec.ts @@ -0,0 +1,48 @@ +export const description = ` +Execution Tests for matrix-matrix AbstractFloat multiplication expression +`; + +import { makeTestGroup } from '../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../gpu_test.js'; +import { Type } from '../../../../util/conversion.js'; +import { onlyConstInputSource, run } from '../expression.js'; + +import { d } from './af_matrix_matrix_multiplication.cache.js'; +import { abstractFloatBinary } from './binary.js'; + +export const g = makeTestGroup(GPUTest); + +g.test('matrix_matrix') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x * y, where x is a matrix and y is a matrix +Accuracy: Correctly rounded +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('common_dim', [2, 3, 4] as const) + .combine('x_rows', [2, 3, 4] as const) + .combine('y_cols', [2, 3, 4] as const) + ) + .beforeAllSubcases(t => { + t.selectDeviceOrSkipTestCase({ requiredFeatures: ['shader-f16'] }); + }) + .fn(async t => { + const x_cols = t.params.common_dim; + const x_rows = t.params.x_rows; + const y_cols = t.params.y_cols; + const y_rows = t.params.common_dim; + + const cases = await d.get(`mat${x_cols}x${x_rows}_mat${y_cols}x${y_rows}`); + await run( + t, + abstractFloatBinary('*'), + [Type.mat(x_cols, x_rows, Type.abstractFloat), Type.mat(y_cols, y_rows, Type.abstractFloat)], + Type.mat(y_cols, x_rows, Type.abstractFloat), + t.params, + cases + ); + }); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts new file mode 100644 index 000000000000..910636297022 --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.cache.ts @@ -0,0 +1,49 @@ +import { FP } from '../../../../util/floating_point.js'; +import { sparseMatrixF64Range, sparseScalarF64Range } from '../../../../util/math.js'; +import { selectNCases } from '../case.js'; +import { makeCaseCache } from '../case_cache.js'; + +// Cases: matCxR_scalar +const mat_scalar_cases = ([2, 3, 4] as const) + .flatMap(cols => + ([2, 3, 4] as const).map(rows => ({ + [`mat${cols}x${rows}_scalar`]: () => { + return selectNCases( + 'binary/af_matrix_scalar_multiplication_mat_scalar', + 50, + FP.abstract.generateMatrixScalarToMatrixCases( + sparseMatrixF64Range(cols, rows), + sparseScalarF64Range(), + 'finite', + FP.abstract.multiplicationMatrixScalarInterval + ) + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +// Cases: scalar_matCxR +const scalar_mat_cases = ([2, 3, 4] as const) + .flatMap(cols => + ([2, 3, 4] as const).map(rows => ({ + [`scalar_mat${cols}x${rows}`]: () => { + return selectNCases( + 'binary/af_matrix_scalar_multiplication_scalar_mat', + 50, + FP.abstract.generateScalarMatrixToMatrixCases( + sparseScalarF64Range(), + sparseMatrixF64Range(cols, rows), + 'finite', + FP.abstract.multiplicationScalarMatrixInterval + ) + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('binary/af_matrix_scalar_multiplication', { + ...mat_scalar_cases, + ...scalar_mat_cases, +}); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.spec.ts new file mode 100644 index 000000000000..c6faabbc8453 --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_scalar_multiplication.spec.ts @@ -0,0 +1,69 @@ +export const description = ` +Execution Tests for matrix-scalar and scalar-matrix AbstractFloat multiplication expression +`; + +import { makeTestGroup } from '../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../gpu_test.js'; +import { Type } from '../../../../util/conversion.js'; +import { onlyConstInputSource, run } from '../expression.js'; + +import { d } from './af_matrix_scalar_multiplication.cache.js'; +import { abstractFloatBinary } from './binary.js'; + +export const g = makeTestGroup(GPUTest); + +g.test('matrix_scalar') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x * y, where x is a matrix and y is a scalar +Accuracy: Correctly rounded +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('cols', [2, 3, 4] as const) + .combine('rows', [2, 3, 4] as const) + ) + .fn(async t => { + const cols = t.params.cols; + const rows = t.params.rows; + const cases = await d.get(`mat${cols}x${rows}_scalar`); + await run( + t, + abstractFloatBinary('*'), + [Type.mat(cols, rows, Type.abstractFloat), Type.abstractFloat], + Type.mat(cols, rows, Type.abstractFloat), + t.params, + cases + ); + }); + +g.test('scalar_matrix') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x * y, where x is a scalar and y is a matrix +Accuracy: Correctly rounded +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('cols', [2, 3, 4] as const) + .combine('rows', [2, 3, 4] as const) + ) + .fn(async t => { + const cols = t.params.cols; + const rows = t.params.rows; + const cases = await d.get(`scalar_mat${cols}x${rows}`); + await run( + t, + abstractFloatBinary('*'), + [Type.abstractFloat, Type.mat(cols, rows, Type.abstractFloat)], + Type.mat(cols, rows, Type.abstractFloat), + t.params, + cases + ); + }); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts index 4c6d1d423234..9b240fdee903 100644 --- a/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_subtraction.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for matrix AbstractFloat subtraction expression +Execution Tests for matrix abstract-float subtraction expression `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_matrix_subtraction.cache.js'; @@ -33,8 +33,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('-'), - [TypeMat(cols, rows, TypeAbstractFloat), TypeMat(cols, rows, TypeAbstractFloat)], - TypeMat(cols, rows, TypeAbstractFloat), + [Type.mat(cols, rows, Type.abstractFloat), Type.mat(cols, rows, Type.abstractFloat)], + Type.mat(cols, rows, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts new file mode 100644 index 000000000000..1401428d3da0 --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.cache.ts @@ -0,0 +1,49 @@ +import { FP } from '../../../../util/floating_point.js'; +import { sparseMatrixF64Range, sparseVectorF64Range } from '../../../../util/math.js'; +import { selectNCases } from '../case.js'; +import { makeCaseCache } from '../case_cache.js'; + +// Cases: matCxR_vecC +const mat_vec_cases = ([2, 3, 4] as const) + .flatMap(cols => + ([2, 3, 4] as const).map(rows => ({ + [`mat${cols}x${rows}_vec${cols}`]: () => { + return selectNCases( + 'binary/af_matrix_vector_multiplication_mat_vec', + 50, + FP.abstract.generateMatrixVectorToVectorCases( + sparseMatrixF64Range(cols, rows), + sparseVectorF64Range(cols), + 'finite', + FP.abstract.multiplicationMatrixVectorInterval + ) + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +// Cases: vecR_matCxR +const vec_mat_cases = ([2, 3, 4] as const) + .flatMap(rows => + ([2, 3, 4] as const).map(cols => ({ + [`vec${rows}_mat${cols}x${rows}`]: () => { + return selectNCases( + 'binary/af_matrix_vector_multiplication_vec_mat', + 50, + FP.abstract.generateVectorMatrixToVectorCases( + sparseVectorF64Range(rows), + sparseMatrixF64Range(cols, rows), + 'finite', + FP.abstract.multiplicationVectorMatrixInterval + ) + ); + }, + })) + ) + .reduce((a, b) => ({ ...a, ...b }), {}); + +export const d = makeCaseCache('binary/af_matrix_vector_multiplication', { + ...mat_vec_cases, + ...vec_mat_cases, +}); diff --git a/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.spec.ts new file mode 100644 index 000000000000..5db78f8369f7 --- /dev/null +++ b/src/webgpu/shader/execution/expression/binary/af_matrix_vector_multiplication.spec.ts @@ -0,0 +1,69 @@ +export const description = ` +Execution Tests for matrix-vector and vector-matrix AbstractFloat multiplication expression +`; + +import { makeTestGroup } from '../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../gpu_test.js'; +import { Type } from '../../../../util/conversion.js'; +import { onlyConstInputSource, run } from '../expression.js'; + +import { d } from './af_matrix_vector_multiplication.cache.js'; +import { abstractFloatBinary } from './binary.js'; + +export const g = makeTestGroup(GPUTest); + +g.test('matrix_vector') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x * y, where x is a matrix and y is a vector +Accuracy: Correctly rounded +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('cols', [2, 3, 4] as const) + .combine('rows', [2, 3, 4] as const) + ) + .fn(async t => { + const cols = t.params.cols; + const rows = t.params.rows; + const cases = await d.get(`mat${cols}x${rows}_vec${cols}`); + await run( + t, + abstractFloatBinary('*'), + [Type.mat(cols, rows, Type.abstractFloat), Type.vec(cols, Type.abstractFloat)], + Type.vec(rows, Type.abstractFloat), + t.params, + cases + ); + }); + +g.test('vector_matrix') + .specURL('https://www.w3.org/TR/WGSL/#floating-point-evaluation') + .desc( + ` +Expression: x * y, where x is a vector and y is is a matrix +Accuracy: Correctly rounded +` + ) + .params(u => + u + .combine('inputSource', onlyConstInputSource) + .combine('cols', [2, 3, 4] as const) + .combine('rows', [2, 3, 4] as const) + ) + .fn(async t => { + const cols = t.params.cols; + const rows = t.params.rows; + const cases = await d.get(`vec${rows}_mat${cols}x${rows}`); + await run( + t, + abstractFloatBinary('*'), + [Type.vec(rows, Type.abstractFloat), Type.mat(cols, rows, Type.abstractFloat)], + Type.vec(cols, Type.abstractFloat), + t.params, + cases + ); + }); diff --git a/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts index 57cf0dbc4768..405de758bd76 100644 --- a/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_multiplication.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for non-matrix AbstractFloat multiplication expression +Execution Tests for non-matrix abstract-float multiplication expression `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_multiplication.cache.js'; @@ -26,8 +26,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('*'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -49,8 +49,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('*'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('*'), - [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(dim, TypeAbstractFloat), + [Type.vec(dim, Type.abstractFloat), Type.abstractFloat], + Type.vec(dim, Type.abstractFloat), t.params, cases ); @@ -93,8 +93,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('*'), - [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], - TypeVec(dim, TypeAbstractFloat), + [Type.abstractFloat, Type.vec(dim, Type.abstractFloat)], + Type.vec(dim, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts index 31a0991e02c4..d743f85ed653 100644 --- a/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_remainder.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix abstract float remainder expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_remainder.cache.js'; @@ -26,8 +26,8 @@ Accuracy: Derived from x - y * trunc(x/y) await run( t, abstractFloatBinary('%'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -49,8 +49,8 @@ Accuracy: Derived from x - y * trunc(x/y) await run( t, abstractFloatBinary('%'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('%'), - [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(dim, TypeAbstractFloat), + [Type.vec(dim, Type.abstractFloat), Type.abstractFloat], + Type.vec(dim, Type.abstractFloat), t.params, cases ); @@ -93,8 +93,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('%'), - [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], - TypeVec(dim, TypeAbstractFloat), + [Type.abstractFloat, Type.vec(dim, Type.abstractFloat)], + Type.vec(dim, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts index 72004cfb1cee..2874a744da2e 100644 --- a/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/af_subtraction.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for non-matrix AbstractFloat subtraction expression +Execution Tests for non-matrix abstract-float subtraction expression `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_subtraction.cache.js'; @@ -26,8 +26,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('-'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -49,8 +49,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('-'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('-'), - [TypeVec(dim, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(dim, TypeAbstractFloat), + [Type.vec(dim, Type.abstractFloat), Type.abstractFloat], + Type.vec(dim, Type.abstractFloat), t.params, cases ); @@ -93,8 +93,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatBinary('-'), - [TypeAbstractFloat, TypeVec(dim, TypeAbstractFloat)], - TypeVec(dim, TypeAbstractFloat), + [Type.abstractFloat, Type.vec(dim, Type.abstractFloat)], + Type.vec(dim, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts index ae8b6ccf483b..ef211af3ed4b 100644 --- a/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/ai_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the abstract int arithmetic binary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractInt, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './ai_arithmetic.cache.js'; @@ -29,8 +29,8 @@ Expression: x + y await run( t, abstractIntBinary('+'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -48,9 +48,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`addition_scalar_vector${vec_size}`); - await run(t, abstractIntBinary('+'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + await run(t, abstractIntBinary('+'), [Type.abstractInt, vec_type], vec_type, t.params, cases); }); g.test('addition_vector_scalar') @@ -65,9 +65,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`addition_vector${vec_size}_scalar`); - await run(t, abstractIntBinary('+'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + await run(t, abstractIntBinary('+'), [vec_type, Type.abstractInt], vec_type, t.params, cases); }); g.test('division') @@ -87,8 +87,8 @@ Expression: x / y await run( t, abstractIntBinary('/'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -106,9 +106,9 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`division_scalar_vector${vec_size}`); - await run(t, abstractIntBinary('/'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + await run(t, abstractIntBinary('/'), [Type.abstractInt, vec_type], vec_type, t.params, cases); }); g.test('division_vector_scalar') @@ -123,9 +123,9 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`division_vector${vec_size}_scalar`); - await run(t, abstractIntBinary('/'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + await run(t, abstractIntBinary('/'), [vec_type, Type.abstractInt], vec_type, t.params, cases); }); g.test('multiplication') @@ -145,8 +145,8 @@ Expression: x * y await run( t, abstractIntBinary('*'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -164,9 +164,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`multiplication_scalar_vector${vec_size}`); - await run(t, abstractIntBinary('*'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + await run(t, abstractIntBinary('*'), [Type.abstractInt, vec_type], vec_type, t.params, cases); }); g.test('multiplication_vector_scalar') @@ -181,9 +181,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`multiplication_vector${vec_size}_scalar`); - await run(t, abstractIntBinary('*'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + await run(t, abstractIntBinary('*'), [vec_type, Type.abstractInt], vec_type, t.params, cases); }); g.test('remainder') @@ -203,8 +203,8 @@ Expression: x % y await run( t, abstractIntBinary('%'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -222,9 +222,9 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`remainder_scalar_vector${vec_size}`); - await run(t, abstractIntBinary('%'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + await run(t, abstractIntBinary('%'), [Type.abstractInt, vec_type], vec_type, t.params, cases); }); g.test('remainder_vector_scalar') @@ -239,9 +239,9 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`remainder_vector${vec_size}_scalar`); - await run(t, abstractIntBinary('%'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + await run(t, abstractIntBinary('%'), [vec_type, Type.abstractInt], vec_type, t.params, cases); }); g.test('subtraction') @@ -261,8 +261,8 @@ Expression: x - y await run( t, abstractIntBinary('-'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -280,9 +280,9 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`subtraction_scalar_vector${vec_size}`); - await run(t, abstractIntBinary('-'), [TypeAbstractInt, vec_type], vec_type, t.params, cases); + await run(t, abstractIntBinary('-'), [Type.abstractInt, vec_type], vec_type, t.params, cases); }); g.test('subtraction_vector_scalar') @@ -297,7 +297,7 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeAbstractInt); + const vec_type = Type.vec(vec_size, Type.abstractInt); const cases = await d.get(`subtraction_vector${vec_size}_scalar`); - await run(t, abstractIntBinary('-'), [vec_type, TypeAbstractInt], vec_type, t.params, cases); + await run(t, abstractIntBinary('-'), [vec_type, Type.abstractInt], vec_type, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/ai_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/ai_comparison.spec.ts index 9d00d0769c18..899e651054ef 100644 --- a/src/webgpu/shader/execution/expression/binary/ai_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/ai_comparison.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for the abstract int comparison expressions +Execution Tests for the abstract-int comparison expressions `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeAbstractInt, bool, abstractInt } from '../../../../util/conversion.js'; +import { bool, abstractInt, Type } from '../../../../util/conversion.js'; import { vectorI64Range } from '../../../../util/math.js'; import { Case } from '../case.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -35,7 +35,7 @@ Expression: x == y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] === v[1])); - await run(t, binary('=='), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); g.test('not_equals') @@ -52,7 +52,7 @@ Expression: x != y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] !== v[1])); - await run(t, binary('!='), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); g.test('less_than') @@ -69,7 +69,7 @@ Expression: x < y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] < v[1])); - await run(t, binary('<'), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); g.test('less_equals') @@ -86,7 +86,7 @@ Expression: x <= y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] <= v[1])); - await run(t, binary('<='), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('<='), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); g.test('greater_than') @@ -103,7 +103,7 @@ Expression: x > y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] > v[1])); - await run(t, binary('>'), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -120,5 +120,5 @@ Expression: x >= y ) .fn(async t => { const cases = vectorI64Range(2).map(v => makeCase(v[0], v[1], v[0] >= v[1])); - await run(t, binary('>='), [TypeAbstractInt, TypeAbstractInt], TypeBool, t.params, cases); + await run(t, binary('>='), [Type.abstractInt, Type.abstractInt], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts b/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts index ead7258635c2..71744b45959b 100644 --- a/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/bitwise.spec.ts @@ -9,7 +9,7 @@ import { abstractIntBits, i32, i32Bits, - Scalar, + ScalarValue, scalarType, u32, u32Bits, @@ -27,27 +27,27 @@ export const g = makeTestGroup(GPUTest); interface ScalarImpl { // builder is a mostly a wrapper around type builders like 'i32Bits' that // handles the (number|bigint) type check. - builder: (bits: bigint | number) => Scalar; + builder: (bits: bigint | number) => ScalarValue; size: 32 | 64; } const kScalarImpls = { i32: { - builder: (bits: bigint | number): Scalar => { + builder: (bits: bigint | number): ScalarValue => { assert(typeof bits === 'number'); return i32Bits(bits); }, size: 32, } as ScalarImpl, u32: { - builder: (bits: bigint | number): Scalar => { + builder: (bits: bigint | number): ScalarValue => { assert(typeof bits === 'number'); return u32Bits(bits); }, size: 32, } as ScalarImpl, 'abstract-int': { - builder: (bits: bigint | number): Scalar => { + builder: (bits: bigint | number): ScalarValue => { assert(typeof bits === 'bigint'); return abstractIntBits(bits); }, diff --git a/src/webgpu/shader/execution/expression/binary/bitwise_shift.spec.ts b/src/webgpu/shader/execution/expression/binary/bitwise_shift.spec.ts index b47d66a47964..e2ed29d3c2ff 100644 --- a/src/webgpu/shader/execution/expression/binary/bitwise_shift.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/bitwise_shift.spec.ts @@ -4,8 +4,8 @@ Execution Tests for the bitwise shift binary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { i32, scalarType, ScalarType, TypeU32, u32 } from '../../../../util/conversion.js'; -import { CaseList } from '../case.js'; +import { i32, scalarType, ScalarType, Type, u32 } from '../../../../util/conversion.js'; +import { Case } from '../case.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -66,9 +66,9 @@ function is_valid_const_shift_right(e1: number, e1Type: string, e2: number) { // Returns all cases of shifting e1 left by [0,63]. If `is_const` is true, cases that are // invalid for const eval are not returned. -function generate_shift_left_cases(e1: number, e1Type: string, is_const: boolean): CaseList { +function generate_shift_left_cases(e1: number, e1Type: string, is_const: boolean): Case[] { const V = e1Type === 'i32' ? i32 : u32; - const cases: CaseList = []; + const cases: Case[] = []; for (let shift = 0; shift < 64; ++shift) { const e2 = shift; if (is_const && !is_valid_const_shift_left(e1, e1Type, e2)) { @@ -82,9 +82,9 @@ function generate_shift_left_cases(e1: number, e1Type: string, is_const: boolean // Returns all cases of shifting e1 right by [0,63]. If `is_const` is true, cases that are // invalid for const eval are not returned. -function generate_shift_right_cases(e1: number, e1Type: string, is_const: boolean): CaseList { +function generate_shift_right_cases(e1: number, e1Type: string, is_const: boolean): Case[] { const V = e1Type === 'i32' ? i32 : u32; - const cases: CaseList = []; + const cases: Case[] = []; for (let shift = 0; shift < 64; ++shift) { const e2 = shift; if (is_const && !is_valid_const_shift_right(e1, e1Type, e2)) { @@ -108,7 +108,7 @@ function makeShiftLeftConcreteCases(inputType: string, inputSource: string, type const V = inputType === 'i32' ? i32 : u32; const is_const = inputSource === 'const'; - const cases: CaseList = [ + const cases: Case[] = [ { input: /* */ [V(0b00000000000000000000000000000001), u32(1)], expected: /**/ V(0b00000000000000000000000000000010), @@ -194,7 +194,7 @@ Shift left (shifted value is concrete) .fn(async t => { const type = scalarType(t.params.type); const cases = makeShiftLeftConcreteCases(t.params.type, t.params.inputSource, type); - await run(t, binary('<<'), [type, TypeU32], type, t.params, cases); + await run(t, binary('<<'), [type, Type.u32], type, t.params, cases); }); g.test('shift_left_concrete_compound') @@ -215,14 +215,14 @@ Shift left (shifted value is concrete) .fn(async t => { const type = scalarType(t.params.type); const cases = makeShiftLeftConcreteCases(t.params.type, t.params.inputSource, type); - await run(t, compoundBinary('<<='), [type, TypeU32], type, t.params, cases); + await run(t, compoundBinary('<<='), [type, Type.u32], type, t.params, cases); }); function makeShiftRightConcreteCases(inputType: string, inputSource: string, type: ScalarType) { const V = inputType === 'i32' ? i32 : u32; const is_const = inputSource === 'const'; - const cases: CaseList = [ + const cases: Case[] = [ { input: /* */ [V(0b00000000000000000000000000000001), u32(1)], expected: /**/ V(0b00000000000000000000000000000000), @@ -319,7 +319,7 @@ Shift right (shifted value is concrete) .fn(async t => { const type = scalarType(t.params.type); const cases = makeShiftRightConcreteCases(t.params.type, t.params.inputSource, type); - await run(t, binary('>>'), [type, TypeU32], type, t.params, cases); + await run(t, binary('>>'), [type, Type.u32], type, t.params, cases); }); g.test('shift_right_concrete_compound') @@ -340,5 +340,5 @@ Shift right (shifted value is concrete) .fn(async t => { const type = scalarType(t.params.type); const cases = makeShiftRightConcreteCases(t.params.type, t.params.inputSource, type); - await run(t, compoundBinary('>>='), [type, TypeU32], type, t.params, cases); + await run(t, compoundBinary('>>='), [type, Type.u32], type, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/bool_logical.spec.ts b/src/webgpu/shader/execution/expression/binary/bool_logical.spec.ts index e3aa448fe3c4..0e76f508240c 100644 --- a/src/webgpu/shader/execution/expression/binary/bool_logical.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/bool_logical.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the boolean binary logical expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { bool, TypeBool } from '../../../../util/conversion.js'; +import { bool, Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -33,7 +33,7 @@ Logical "and". Component-wise when T is a vector. Evaluates both e1 and e2. { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, binary('&'), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('&'), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('and_compound') @@ -55,7 +55,7 @@ Logical "and". Component-wise when T is a vector. Evaluates both e1 and e2. { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, compoundBinary('&='), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, compoundBinary('&='), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('and_short_circuit') @@ -75,7 +75,7 @@ short_circuiting "and". Yields true if both e1 and e2 are true; evaluates e2 onl { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, binary('&&'), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('&&'), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('or') @@ -97,7 +97,7 @@ Logical "or". Component-wise when T is a vector. Evaluates both e1 and e2. { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, binary('|'), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('|'), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('or_compound') @@ -119,7 +119,7 @@ Logical "or". Component-wise when T is a vector. Evaluates both e1 and e2. { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, compoundBinary('|='), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, compoundBinary('|='), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('or_short_circuit') @@ -139,7 +139,7 @@ short_circuiting "and". Yields true if both e1 and e2 are true; evaluates e2 onl { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, binary('||'), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('||'), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('equals') @@ -161,7 +161,7 @@ Equality. Component-wise when T is a vector. { input: [bool(true), bool(true)], expected: bool(true) }, ]; - await run(t, binary('=='), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.bool, Type.bool], Type.bool, t.params, cases); }); g.test('not_equals') @@ -183,5 +183,5 @@ Equality. Component-wise when T is a vector. { input: [bool(true), bool(true)], expected: bool(false) }, ]; - await run(t, binary('!='), [TypeBool, TypeBool], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.bool, Type.bool], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts index 7f94c7e307a9..d9aa44bba0e2 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_addition.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f16 addition expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -28,7 +28,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('+'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('+'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector') @@ -47,7 +47,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('+'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('+'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('scalar_compound') @@ -68,7 +68,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('+='), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, compoundBinary('+='), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector_scalar') @@ -91,8 +91,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -118,8 +118,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('+='), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -145,8 +145,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeF16, TypeVec(dim, TypeF16)], - TypeVec(dim, TypeF16), + [Type.f16, Type.vec(dim, Type.f16)], + Type.vec(dim, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_comparison.cache.ts b/src/webgpu/shader/execution/expression/binary/f16_comparison.cache.ts index 92d926a412b9..c0c0d4f8a4a6 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_comparison.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_comparison.cache.ts @@ -1,5 +1,5 @@ import { anyOf } from '../../../../util/compare.js'; -import { bool, f16, Scalar } from '../../../../util/conversion.js'; +import { bool, f16, ScalarValue } from '../../../../util/conversion.js'; import { flushSubnormalNumberF16, vectorF16Range } from '../../../../util/math.js'; import { Case } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; @@ -11,7 +11,7 @@ import { makeCaseCache } from '../case_cache.js'; function makeCase( lhs: number, rhs: number, - truthFunc: (lhs: Scalar, rhs: Scalar) => boolean + truthFunc: (lhs: ScalarValue, rhs: ScalarValue) => boolean ): Case { // Subnormal float values may be flushed at any time. // https://www.w3.org/TR/WGSL/#floating-point-evaluation @@ -19,7 +19,7 @@ function makeCase( const f16_rhs = f16(rhs); const lhs_options = new Set([f16_lhs, f16(flushSubnormalNumberF16(lhs))]); const rhs_options = new Set([f16_rhs, f16(flushSubnormalNumberF16(rhs))]); - const expected: Array = []; + const expected: Array = []; lhs_options.forEach(l => { rhs_options.forEach(r => { const result = bool(truthFunc(l, r)); @@ -34,7 +34,7 @@ function makeCase( export const d = makeCaseCache('binary/f16_logical', { equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) === (rhs.value as number); }; @@ -43,7 +43,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) === (rhs.value as number); }; @@ -52,7 +52,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, not_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) !== (rhs.value as number); }; @@ -61,7 +61,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, not_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) !== (rhs.value as number); }; @@ -70,7 +70,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, less_than_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) < (rhs.value as number); }; @@ -79,7 +79,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, less_than_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) < (rhs.value as number); }; @@ -88,7 +88,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, less_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) <= (rhs.value as number); }; @@ -97,7 +97,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, less_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) <= (rhs.value as number); }; @@ -106,7 +106,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, greater_than_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) > (rhs.value as number); }; @@ -115,7 +115,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, greater_than_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) > (rhs.value as number); }; @@ -124,7 +124,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, greater_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) >= (rhs.value as number); }; @@ -133,7 +133,7 @@ export const d = makeCaseCache('binary/f16_logical', { }); }, greater_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) >= (rhs.value as number); }; diff --git a/src/webgpu/shader/execution/expression/binary/f16_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_comparison.spec.ts index c84080983de5..b978cd3c99fe 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_comparison.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the f16 comparison operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeF16 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary } from './binary.js'; @@ -30,7 +30,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'equals_const' : 'equals_non_const' ); - await run(t, binary('=='), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.f16, Type.f16], Type.bool, t.params, cases); }); g.test('not_equals') @@ -51,7 +51,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'not_equals_const' : 'not_equals_non_const' ); - await run(t, binary('!='), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.f16, Type.f16], Type.bool, t.params, cases); }); g.test('less_than') @@ -72,7 +72,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'less_than_const' : 'less_than_non_const' ); - await run(t, binary('<'), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.f16, Type.f16], Type.bool, t.params, cases); }); g.test('less_equals') @@ -93,7 +93,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'less_equals_const' : 'less_equals_non_const' ); - await run(t, binary('<='), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('<='), [Type.f16, Type.f16], Type.bool, t.params, cases); }); g.test('greater_than') @@ -114,7 +114,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'greater_than_const' : 'greater_than_non_const' ); - await run(t, binary('>'), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.f16, Type.f16], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -135,5 +135,5 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'greater_equals_const' : 'greater_equals_non_const' ); - await run(t, binary('>='), [TypeF16, TypeF16], TypeBool, t.params, cases); + await run(t, binary('>='), [Type.f16, Type.f16], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts index 7dfc13f81a2f..8a155024db98 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_division.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f16 division expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -28,7 +28,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('/'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('/'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector') @@ -47,7 +47,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('/'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('/'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('scalar_compound') @@ -68,7 +68,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('/='), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, compoundBinary('/='), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector_scalar') @@ -91,8 +91,8 @@ Accuracy: Correctly rounded await run( t, binary('/'), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -118,8 +118,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('/='), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -145,8 +145,8 @@ Accuracy: Correctly rounded await run( t, binary('/'), - [TypeF16, TypeVec(dim, TypeF16)], - TypeVec(dim, TypeF16), + [Type.f16, Type.vec(dim, Type.f16)], + Type.vec(dim, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_addition.spec.ts index daf768a5365c..7c34b0cadd87 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_addition.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix f16 addition expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -38,8 +38,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeMat(cols, rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('+='), - [TypeMat(cols, rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_matrix_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_matrix_multiplication.spec.ts index 69c56c60c368..80ca78f7f5bd 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_matrix_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_matrix_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-matrix f16 multiplication expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -44,8 +44,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(x_cols, x_rows, TypeF16), TypeMat(y_cols, y_rows, TypeF16)], - TypeMat(y_cols, x_rows, TypeF16), + [Type.mat(x_cols, x_rows, Type.f16), Type.mat(y_cols, y_rows, Type.f16)], + Type.mat(y_cols, x_rows, Type.f16), t.params, cases ); @@ -82,8 +82,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeMat(x_cols, x_rows, TypeF16), TypeMat(y_cols, y_rows, TypeF16)], - TypeMat(y_cols, x_rows, TypeF16), + [Type.mat(x_cols, x_rows, Type.f16), Type.mat(y_cols, y_rows, Type.f16)], + Type.mat(y_cols, x_rows, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts index 338d6d021bb5..aa7087738a5e 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_scalar_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-scalar and scalar-matrix f16 multiplication expressio import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -40,8 +40,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(cols, rows, TypeF16), TypeF16], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.f16], + Type.mat(cols, rows, Type.f16), t.params, cases ); @@ -75,8 +75,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeMat(cols, rows, TypeF16), TypeF16], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.f16], + Type.mat(cols, rows, Type.f16), t.params, cases ); @@ -110,8 +110,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeF16, TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.f16, Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_subtraction.spec.ts index 442c31ef82e9..e8e13d902a0e 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_subtraction.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix f16 subtraction expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -38,8 +38,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeMat(cols, rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); @@ -71,8 +71,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('-='), - [TypeMat(cols, rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_matrix_vector_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_matrix_vector_multiplication.spec.ts index 9715fe681e35..557a7cead847 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_matrix_vector_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_matrix_vector_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-vector and vector-matrix f16 multiplication expressio import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeMat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -40,8 +40,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(cols, rows, TypeF16), TypeVec(cols, TypeF16)], - TypeVec(rows, TypeF16), + [Type.mat(cols, rows, Type.f16), Type.vec(cols, Type.f16)], + Type.vec(rows, Type.f16), t.params, cases ); @@ -75,8 +75,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeVec(rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeVec(cols, TypeF16), + [Type.vec(rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.vec(cols, Type.f16), t.params, cases ); @@ -105,8 +105,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeVec(rows, TypeF16), TypeMat(cols, rows, TypeF16)], - TypeVec(cols, TypeF16), + [Type.vec(rows, Type.f16), Type.mat(cols, rows, Type.f16)], + Type.vec(cols, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts index 005a9a1e64af..81339d9266b5 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f16 multiplication expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -28,7 +28,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('*'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('*'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector') @@ -47,7 +47,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('*'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('*'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('scalar_compound') @@ -68,7 +68,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('*='), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, compoundBinary('*='), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector_scalar') @@ -91,8 +91,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -118,8 +118,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -145,8 +145,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeF16, TypeVec(dim, TypeF16)], - TypeVec(dim, TypeF16), + [Type.f16, Type.vec(dim, Type.f16)], + Type.vec(dim, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts index c2f5cd7af11f..0fe1cc53c662 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_remainder.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f16 remainder expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -28,7 +28,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('%'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('%'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector') @@ -47,7 +47,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('%'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('%'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('scalar_compound') @@ -68,7 +68,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('%='), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, compoundBinary('%='), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector_scalar') @@ -91,8 +91,8 @@ Accuracy: Correctly rounded await run( t, binary('%'), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -118,8 +118,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('%='), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -145,8 +145,8 @@ Accuracy: Correctly rounded await run( t, binary('%'), - [TypeF16, TypeVec(dim, TypeF16)], - TypeVec(dim, TypeF16), + [Type.f16, Type.vec(dim, Type.f16)], + Type.vec(dim, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts index a458885ae8ce..6b29aad6ad78 100644 --- a/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f16_subtraction.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f16 subtraction expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -28,7 +28,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('-'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('-'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector') @@ -47,7 +47,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('-'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, binary('-'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('scalar_compound') @@ -68,7 +68,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('-='), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, compoundBinary('-='), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('vector_scalar') @@ -91,8 +91,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -118,8 +118,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('-='), - [TypeVec(dim, TypeF16), TypeF16], - TypeVec(dim, TypeF16), + [Type.vec(dim, Type.f16), Type.f16], + Type.vec(dim, Type.f16), t.params, cases ); @@ -145,8 +145,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeF16, TypeVec(dim, TypeF16)], - TypeVec(dim, TypeF16), + [Type.f16, Type.vec(dim, Type.f16)], + Type.vec(dim, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts index 6bd8b0e7bdb7..9a502ae67719 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_addition.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f32 addition expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('+'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('+'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector') @@ -41,7 +41,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('+'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('+'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('scalar_compound') @@ -59,7 +59,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('+='), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, compoundBinary('+='), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector_scalar') @@ -79,8 +79,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -103,8 +103,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('+='), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -127,8 +127,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeF32, TypeVec(dim, TypeF32)], - TypeVec(dim, TypeF32), + [Type.f32, Type.vec(dim, Type.f32)], + Type.vec(dim, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_comparison.cache.ts b/src/webgpu/shader/execution/expression/binary/f32_comparison.cache.ts index 4c16fc55f0e5..28fb22e8202a 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_comparison.cache.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_comparison.cache.ts @@ -1,5 +1,5 @@ import { anyOf } from '../../../../util/compare.js'; -import { bool, f32, Scalar } from '../../../../util/conversion.js'; +import { bool, f32, ScalarValue } from '../../../../util/conversion.js'; import { flushSubnormalNumberF32, vectorF32Range } from '../../../../util/math.js'; import { Case } from '../case.js'; import { makeCaseCache } from '../case_cache.js'; @@ -11,7 +11,7 @@ import { makeCaseCache } from '../case_cache.js'; function makeCase( lhs: number, rhs: number, - truthFunc: (lhs: Scalar, rhs: Scalar) => boolean + truthFunc: (lhs: ScalarValue, rhs: ScalarValue) => boolean ): Case { // Subnormal float values may be flushed at any time. // https://www.w3.org/TR/WGSL/#floating-point-evaluation @@ -19,7 +19,7 @@ function makeCase( const f32_rhs = f32(rhs); const lhs_options = new Set([f32_lhs, f32(flushSubnormalNumberF32(lhs))]); const rhs_options = new Set([f32_rhs, f32(flushSubnormalNumberF32(rhs))]); - const expected: Array = []; + const expected: Array = []; lhs_options.forEach(l => { rhs_options.forEach(r => { const result = bool(truthFunc(l, r)); @@ -34,7 +34,7 @@ function makeCase( export const d = makeCaseCache('binary/f32_logical', { equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) === (rhs.value as number); }; @@ -43,7 +43,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) === (rhs.value as number); }; @@ -52,7 +52,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, not_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) !== (rhs.value as number); }; @@ -61,7 +61,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, not_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) !== (rhs.value as number); }; @@ -70,7 +70,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, less_than_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) < (rhs.value as number); }; @@ -79,7 +79,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, less_than_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) < (rhs.value as number); }; @@ -88,7 +88,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, less_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) <= (rhs.value as number); }; @@ -97,7 +97,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, less_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) <= (rhs.value as number); }; @@ -106,7 +106,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, greater_than_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) > (rhs.value as number); }; @@ -115,7 +115,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, greater_than_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) > (rhs.value as number); }; @@ -124,7 +124,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, greater_equals_non_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) >= (rhs.value as number); }; @@ -133,7 +133,7 @@ export const d = makeCaseCache('binary/f32_logical', { }); }, greater_equals_const: () => { - const truthFunc = (lhs: Scalar, rhs: Scalar): boolean => { + const truthFunc = (lhs: ScalarValue, rhs: ScalarValue): boolean => { return (lhs.value as number) >= (rhs.value as number); }; diff --git a/src/webgpu/shader/execution/expression/binary/f32_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_comparison.spec.ts index e5833a0f9f33..42eb8934a440 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_comparison.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the f32 comparison operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeF32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary } from './binary.js'; @@ -27,7 +27,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'equals_const' : 'equals_non_const' ); - await run(t, binary('=='), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.f32, Type.f32], Type.bool, t.params, cases); }); g.test('not_equals') @@ -45,7 +45,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'not_equals_const' : 'not_equals_non_const' ); - await run(t, binary('!='), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.f32, Type.f32], Type.bool, t.params, cases); }); g.test('less_than') @@ -63,7 +63,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'less_than_const' : 'less_than_non_const' ); - await run(t, binary('<'), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.f32, Type.f32], Type.bool, t.params, cases); }); g.test('less_equals') @@ -81,7 +81,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'less_equals_const' : 'less_equals_non_const' ); - await run(t, binary('<='), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('<='), [Type.f32, Type.f32], Type.bool, t.params, cases); }); g.test('greater_than') @@ -99,7 +99,7 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'greater_than_const' : 'greater_than_non_const' ); - await run(t, binary('>'), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.f32, Type.f32], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -117,5 +117,5 @@ Accuracy: Correct result const cases = await d.get( t.params.inputSource === 'const' ? 'greater_equals_const' : 'greater_equals_non_const' ); - await run(t, binary('>='), [TypeF32, TypeF32], TypeBool, t.params, cases); + await run(t, binary('>='), [Type.f32, Type.f32], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts index 0c8dd293f57d..bdd71e69eb52 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_division.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f32 division expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -25,7 +25,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('/'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('/'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector') @@ -41,7 +41,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('/'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('/'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('scalar_compound') @@ -59,7 +59,7 @@ Accuracy: 2.5 ULP for |y| in the range [2^-126, 2^126] const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('/='), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, compoundBinary('/='), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector_scalar') @@ -79,8 +79,8 @@ Accuracy: Correctly rounded await run( t, binary('/'), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -103,8 +103,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('/='), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -127,8 +127,8 @@ Accuracy: Correctly rounded await run( t, binary('/'), - [TypeF32, TypeVec(dim, TypeF32)], - TypeVec(dim, TypeF32), + [Type.f32, Type.vec(dim, Type.f32)], + Type.vec(dim, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_addition.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_addition.spec.ts index 4fcb4d08927d..06a4ac47cc5b 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_addition.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_addition.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix f32 addition expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -35,8 +35,8 @@ Accuracy: Correctly rounded await run( t, binary('+'), - [TypeMat(cols, rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); @@ -65,8 +65,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('+='), - [TypeMat(cols, rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_matrix_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_matrix_multiplication.spec.ts index ad34d642d26e..1ff7799f4625 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_matrix_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_matrix_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-matrix f32 multiplication expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -41,8 +41,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(x_cols, x_rows, TypeF32), TypeMat(y_cols, y_rows, TypeF32)], - TypeMat(y_cols, x_rows, TypeF32), + [Type.mat(x_cols, x_rows, Type.f32), Type.mat(y_cols, y_rows, Type.f32)], + Type.mat(y_cols, x_rows, Type.f32), t.params, cases ); @@ -76,8 +76,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeMat(x_cols, x_rows, TypeF32), TypeMat(y_cols, y_rows, TypeF32)], - TypeMat(y_cols, x_rows, TypeF32), + [Type.mat(x_cols, x_rows, Type.f32), Type.mat(y_cols, y_rows, Type.f32)], + Type.mat(y_cols, x_rows, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts index 0558862d065d..e8771d19eb5d 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_scalar_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-scalar and scalar-matrix f32 multiplication expressio import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -37,8 +37,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(cols, rows, TypeF32), TypeF32], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.f32], + Type.mat(cols, rows, Type.f32), t.params, cases ); @@ -69,8 +69,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeMat(cols, rows, TypeF32), TypeF32], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.f32], + Type.mat(cols, rows, Type.f32), t.params, cases ); @@ -101,8 +101,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeF32, TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.f32, Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_subtraction.spec.ts index 8bcf9a47895c..31565ba598d5 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_subtraction.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix f32 subtraction expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeMat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -35,8 +35,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeMat(cols, rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); @@ -65,8 +65,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('-='), - [TypeMat(cols, rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_matrix_vector_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_matrix_vector_multiplication.spec.ts index a04a28cfeff3..8cd7ed49fe0a 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_matrix_vector_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_matrix_vector_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for matrix-vector and vector-matrix f32 multiplication expressio import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeMat, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -37,8 +37,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeMat(cols, rows, TypeF32), TypeVec(cols, TypeF32)], - TypeVec(rows, TypeF32), + [Type.mat(cols, rows, Type.f32), Type.vec(cols, Type.f32)], + Type.vec(rows, Type.f32), t.params, cases ); @@ -69,8 +69,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeVec(rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeVec(cols, TypeF32), + [Type.vec(rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.vec(cols, Type.f32), t.params, cases ); @@ -96,8 +96,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeVec(rows, TypeF32), TypeMat(cols, rows, TypeF32)], - TypeVec(cols, TypeF32), + [Type.vec(rows, Type.f32), Type.mat(cols, rows, Type.f32)], + Type.vec(cols, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts index 77e670795d2d..478ca71ef0fc 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_multiplication.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f32 multiplication expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('*'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('*'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector') @@ -41,7 +41,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('*'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('*'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('scalar_compound') @@ -59,7 +59,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('*='), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, compoundBinary('*='), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector_scalar') @@ -79,8 +79,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -103,8 +103,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('*='), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -127,8 +127,8 @@ Accuracy: Correctly rounded await run( t, binary('*'), - [TypeF32, TypeVec(dim, TypeF32)], - TypeVec(dim, TypeF32), + [Type.f32, Type.vec(dim, Type.f32)], + Type.vec(dim, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts index b61d3ecc633a..3a9acb02e095 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_remainder.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f32 remainder expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -25,7 +25,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('%'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('%'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector') @@ -41,7 +41,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('%'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('%'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('scalar_compound') @@ -59,7 +59,7 @@ Accuracy: Derived from x - y * trunc(x/y) const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('%='), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, compoundBinary('%='), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector_scalar') @@ -79,8 +79,8 @@ Accuracy: Correctly rounded await run( t, binary('%'), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -103,8 +103,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('%='), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -127,8 +127,8 @@ Accuracy: Correctly rounded await run( t, binary('%'), - [TypeF32, TypeVec(dim, TypeF32)], - TypeVec(dim, TypeF32), + [Type.f32, Type.vec(dim, Type.f32)], + Type.vec(dim, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts b/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts index e873c6ebc3b1..55097390e935 100644 --- a/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/f32_subtraction.spec.ts @@ -4,7 +4,7 @@ Execution Tests for non-matrix f32 subtraction expression import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -25,7 +25,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, binary('-'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('-'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector') @@ -41,7 +41,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' // Using vectorize to generate vector cases based on scalar cases ); - await run(t, binary('-'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, binary('-'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('scalar_compound') @@ -59,7 +59,7 @@ Accuracy: Correctly rounded const cases = await d.get( t.params.inputSource === 'const' ? 'scalar_const' : 'scalar_non_const' ); - await run(t, compoundBinary('-='), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, compoundBinary('-='), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('vector_scalar') @@ -79,8 +79,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -103,8 +103,8 @@ Accuracy: Correctly rounded await run( t, compoundBinary('-='), - [TypeVec(dim, TypeF32), TypeF32], - TypeVec(dim, TypeF32), + [Type.vec(dim, Type.f32), Type.f32], + Type.vec(dim, Type.f32), t.params, cases ); @@ -127,8 +127,8 @@ Accuracy: Correctly rounded await run( t, binary('-'), - [TypeF32, TypeVec(dim, TypeF32)], - TypeVec(dim, TypeF32), + [Type.f32, Type.vec(dim, Type.f32)], + Type.vec(dim, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/binary/i32_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/binary/i32_arithmetic.spec.ts index ef201f66689f..ef8ea0044782 100644 --- a/src/webgpu/shader/execution/expression/binary/i32_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/i32_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the i32 arithmetic binary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeI32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -24,7 +24,7 @@ Expression: x + y ) .fn(async t => { const cases = await d.get('addition'); - await run(t, binary('+'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, binary('+'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('addition_compound') @@ -39,7 +39,7 @@ Expression: x += y ) .fn(async t => { const cases = await d.get('addition'); - await run(t, compoundBinary('+='), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, compoundBinary('+='), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('subtraction') @@ -54,7 +54,7 @@ Expression: x - y ) .fn(async t => { const cases = await d.get('subtraction'); - await run(t, binary('-'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, binary('-'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('subtraction_compound') @@ -69,7 +69,7 @@ Expression: x -= y ) .fn(async t => { const cases = await d.get('subtraction'); - await run(t, compoundBinary('-='), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, compoundBinary('-='), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('multiplication') @@ -84,7 +84,7 @@ Expression: x * y ) .fn(async t => { const cases = await d.get('multiplication'); - await run(t, binary('*'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, binary('*'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('multiplication_compound') @@ -99,7 +99,7 @@ Expression: x *= y ) .fn(async t => { const cases = await d.get('multiplication'); - await run(t, compoundBinary('*='), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, compoundBinary('*='), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('division') @@ -116,7 +116,7 @@ Expression: x / y const cases = await d.get( t.params.inputSource === 'const' ? 'division_const' : 'division_non_const' ); - await run(t, binary('/'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, binary('/'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('division_compound') @@ -133,7 +133,7 @@ Expression: x /= y const cases = await d.get( t.params.inputSource === 'const' ? 'division_const' : 'division_non_const' ); - await run(t, compoundBinary('/='), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, compoundBinary('/='), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('remainder') @@ -150,7 +150,7 @@ Expression: x % y const cases = await d.get( t.params.inputSource === 'const' ? 'remainder_const' : 'remainder_non_const' ); - await run(t, binary('%'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, binary('%'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('remainder_compound') @@ -167,7 +167,7 @@ Expression: x %= y const cases = await d.get( t.params.inputSource === 'const' ? 'remainder_const' : 'remainder_non_const' ); - await run(t, compoundBinary('%='), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, compoundBinary('%='), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('addition_scalar_vector') @@ -182,9 +182,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`addition_scalar_vector${vec_size}`); - await run(t, binary('+'), [TypeI32, vec_type], vec_type, t.params, cases); + await run(t, binary('+'), [Type.i32, vec_type], vec_type, t.params, cases); }); g.test('addition_vector_scalar') @@ -199,9 +199,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`addition_vector${vec_size}_scalar`); - await run(t, binary('+'), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, binary('+'), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('addition_vector_scalar_compound') @@ -216,9 +216,9 @@ Expression: x += y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`addition_vector${vec_size}_scalar`); - await run(t, compoundBinary('+='), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, compoundBinary('+='), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('subtraction_scalar_vector') @@ -233,9 +233,9 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`subtraction_scalar_vector${vec_size}`); - await run(t, binary('-'), [TypeI32, vec_type], vec_type, t.params, cases); + await run(t, binary('-'), [Type.i32, vec_type], vec_type, t.params, cases); }); g.test('subtraction_vector_scalar') @@ -250,9 +250,9 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`subtraction_vector${vec_size}_scalar`); - await run(t, binary('-'), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, binary('-'), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('subtraction_vector_scalar_compound') @@ -267,9 +267,9 @@ Expression: x -= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`subtraction_vector${vec_size}_scalar`); - await run(t, compoundBinary('-='), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, compoundBinary('-='), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('multiplication_scalar_vector') @@ -284,9 +284,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`multiplication_scalar_vector${vec_size}`); - await run(t, binary('*'), [TypeI32, vec_type], vec_type, t.params, cases); + await run(t, binary('*'), [Type.i32, vec_type], vec_type, t.params, cases); }); g.test('multiplication_vector_scalar') @@ -301,9 +301,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`multiplication_vector${vec_size}_scalar`); - await run(t, binary('*'), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, binary('*'), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('multiplication_vector_scalar_compound') @@ -318,9 +318,9 @@ Expression: x *= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const cases = await d.get(`multiplication_vector${vec_size}_scalar`); - await run(t, compoundBinary('*='), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, compoundBinary('*='), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('division_scalar_vector') @@ -335,10 +335,10 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_scalar_vector${vec_size}_${source}`); - await run(t, binary('/'), [TypeI32, vec_type], vec_type, t.params, cases); + await run(t, binary('/'), [Type.i32, vec_type], vec_type, t.params, cases); }); g.test('division_vector_scalar') @@ -353,10 +353,10 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_vector${vec_size}_scalar_${source}`); - await run(t, binary('/'), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, binary('/'), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('division_vector_scalar_compound') @@ -371,10 +371,10 @@ Expression: x /= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_vector${vec_size}_scalar_${source}`); - await run(t, compoundBinary('/='), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, compoundBinary('/='), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('remainder_scalar_vector') @@ -389,10 +389,10 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_scalar_vector${vec_size}_${source}`); - await run(t, binary('%'), [TypeI32, vec_type], vec_type, t.params, cases); + await run(t, binary('%'), [Type.i32, vec_type], vec_type, t.params, cases); }); g.test('remainder_vector_scalar') @@ -407,10 +407,10 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_vector${vec_size}_scalar_${source}`); - await run(t, binary('%'), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, binary('%'), [vec_type, Type.i32], vec_type, t.params, cases); }); g.test('remainder_vector_scalar_compound') @@ -425,8 +425,8 @@ Expression: x %= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeI32); + const vec_type = Type.vec(vec_size, Type.i32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_vector${vec_size}_scalar_${source}`); - await run(t, compoundBinary('%='), [vec_type, TypeI32], vec_type, t.params, cases); + await run(t, compoundBinary('%='), [vec_type, Type.i32], vec_type, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/i32_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/i32_comparison.spec.ts index c07d09a058ed..9b6566c9a4a8 100644 --- a/src/webgpu/shader/execution/expression/binary/i32_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/i32_comparison.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the i32 comparison expressions import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeI32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary } from './binary.js'; @@ -24,7 +24,7 @@ Expression: x == y ) .fn(async t => { const cases = await d.get('equals'); - await run(t, binary('=='), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.i32, Type.i32], Type.bool, t.params, cases); }); g.test('not_equals') @@ -39,7 +39,7 @@ Expression: x != y ) .fn(async t => { const cases = await d.get('not_equals'); - await run(t, binary('!='), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.i32, Type.i32], Type.bool, t.params, cases); }); g.test('less_than') @@ -54,7 +54,7 @@ Expression: x < y ) .fn(async t => { const cases = await d.get('less_than'); - await run(t, binary('<'), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.i32, Type.i32], Type.bool, t.params, cases); }); g.test('less_equals') @@ -69,7 +69,7 @@ Expression: x <= y ) .fn(async t => { const cases = await d.get('less_equal'); - await run(t, binary('<='), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('<='), [Type.i32, Type.i32], Type.bool, t.params, cases); }); g.test('greater_than') @@ -84,7 +84,7 @@ Expression: x > y ) .fn(async t => { const cases = await d.get('greater_than'); - await run(t, binary('>'), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.i32, Type.i32], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -99,5 +99,5 @@ Expression: x >= y ) .fn(async t => { const cases = await d.get('greater_equal'); - await run(t, binary('>='), [TypeI32, TypeI32], TypeBool, t.params, cases); + await run(t, binary('>='), [Type.i32, Type.i32], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/u32_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/binary/u32_arithmetic.spec.ts index 28c25fef8dc9..6df16f303c7f 100644 --- a/src/webgpu/shader/execution/expression/binary/u32_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/u32_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the u32 arithmetic binary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeU32, TypeVec } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary, compoundBinary } from './binary.js'; @@ -24,7 +24,7 @@ Expression: x + y ) .fn(async t => { const cases = await d.get('addition'); - await run(t, binary('+'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, binary('+'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('addition_compound') @@ -39,7 +39,7 @@ Expression: x += y ) .fn(async t => { const cases = await d.get('addition'); - await run(t, compoundBinary('+='), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, compoundBinary('+='), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('subtraction') @@ -54,7 +54,7 @@ Expression: x - y ) .fn(async t => { const cases = await d.get('subtraction'); - await run(t, binary('-'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, binary('-'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('subtraction_compound') @@ -69,7 +69,7 @@ Expression: x -= y ) .fn(async t => { const cases = await d.get('subtraction'); - await run(t, compoundBinary('-='), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, compoundBinary('-='), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('multiplication') @@ -84,7 +84,7 @@ Expression: x * y ) .fn(async t => { const cases = await d.get('multiplication'); - await run(t, binary('*'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, binary('*'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('multiplication_compound') @@ -99,7 +99,7 @@ Expression: x *= y ) .fn(async t => { const cases = await d.get('multiplication'); - await run(t, compoundBinary('*='), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, compoundBinary('*='), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('division') @@ -116,7 +116,7 @@ Expression: x / y const cases = await d.get( t.params.inputSource === 'const' ? 'division_const' : 'division_non_const' ); - await run(t, binary('/'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, binary('/'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('division_compound') @@ -133,7 +133,7 @@ Expression: x /= y const cases = await d.get( t.params.inputSource === 'const' ? 'division_const' : 'division_non_const' ); - await run(t, compoundBinary('/='), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, compoundBinary('/='), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('remainder') @@ -150,7 +150,7 @@ Expression: x % y const cases = await d.get( t.params.inputSource === 'const' ? 'remainder_const' : 'remainder_non_const' ); - await run(t, binary('%'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, binary('%'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('remainder_compound') @@ -167,7 +167,7 @@ Expression: x %= y const cases = await d.get( t.params.inputSource === 'const' ? 'remainder_const' : 'remainder_non_const' ); - await run(t, compoundBinary('%='), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, compoundBinary('%='), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('addition_scalar_vector') @@ -182,9 +182,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`addition_scalar_vector${vec_size}`); - await run(t, binary('+'), [TypeU32, vec_type], vec_type, t.params, cases); + await run(t, binary('+'), [Type.u32, vec_type], vec_type, t.params, cases); }); g.test('addition_vector_scalar') @@ -199,9 +199,9 @@ Expression: x + y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`addition_vector${vec_size}_scalar`); - await run(t, binary('+'), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, binary('+'), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('addition_vector_scalar_compound') @@ -216,9 +216,9 @@ Expression: x += y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`addition_vector${vec_size}_scalar`); - await run(t, compoundBinary('+='), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, compoundBinary('+='), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('subtraction_scalar_vector') @@ -233,9 +233,9 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`subtraction_scalar_vector${vec_size}`); - await run(t, binary('-'), [TypeU32, vec_type], vec_type, t.params, cases); + await run(t, binary('-'), [Type.u32, vec_type], vec_type, t.params, cases); }); g.test('subtraction_vector_scalar') @@ -250,9 +250,9 @@ Expression: x - y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`subtraction_vector${vec_size}_scalar`); - await run(t, binary('-'), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, binary('-'), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('subtraction_vector_scalar_compound') @@ -267,9 +267,9 @@ Expression: x -= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`subtraction_vector${vec_size}_scalar`); - await run(t, compoundBinary('-='), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, compoundBinary('-='), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('multiplication_scalar_vector') @@ -284,9 +284,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`multiplication_scalar_vector${vec_size}`); - await run(t, binary('*'), [TypeU32, vec_type], vec_type, t.params, cases); + await run(t, binary('*'), [Type.u32, vec_type], vec_type, t.params, cases); }); g.test('multiplication_vector_scalar') @@ -301,9 +301,9 @@ Expression: x * y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`multiplication_vector${vec_size}_scalar`); - await run(t, binary('*'), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, binary('*'), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('multiplication_vector_scalar_compound') @@ -318,9 +318,9 @@ Expression: x *= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const cases = await d.get(`multiplication_vector${vec_size}_scalar`); - await run(t, compoundBinary('*='), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, compoundBinary('*='), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('division_scalar_vector') @@ -335,10 +335,10 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_scalar_vector${vec_size}_${source}`); - await run(t, binary('/'), [TypeU32, vec_type], vec_type, t.params, cases); + await run(t, binary('/'), [Type.u32, vec_type], vec_type, t.params, cases); }); g.test('division_vector_scalar') @@ -353,10 +353,10 @@ Expression: x / y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_vector${vec_size}_scalar_${source}`); - await run(t, binary('/'), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, binary('/'), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('division_vector_scalar_compound') @@ -371,10 +371,10 @@ Expression: x /= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`division_vector${vec_size}_scalar_${source}`); - await run(t, compoundBinary('/='), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, compoundBinary('/='), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('remainder_scalar_vector') @@ -389,10 +389,10 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_rhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_scalar_vector${vec_size}_${source}`); - await run(t, binary('%'), [TypeU32, vec_type], vec_type, t.params, cases); + await run(t, binary('%'), [Type.u32, vec_type], vec_type, t.params, cases); }); g.test('remainder_vector_scalar') @@ -407,10 +407,10 @@ Expression: x % y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_vector${vec_size}_scalar_${source}`); - await run(t, binary('%'), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, binary('%'), [vec_type, Type.u32], vec_type, t.params, cases); }); g.test('remainder_vector_scalar_compound') @@ -425,8 +425,8 @@ Expression: x %= y ) .fn(async t => { const vec_size = t.params.vectorize_lhs; - const vec_type = TypeVec(vec_size, TypeU32); + const vec_type = Type.vec(vec_size, Type.u32); const source = t.params.inputSource === 'const' ? 'const' : 'non_const'; const cases = await d.get(`remainder_vector${vec_size}_scalar_${source}`); - await run(t, compoundBinary('%='), [vec_type, TypeU32], vec_type, t.params, cases); + await run(t, compoundBinary('%='), [vec_type, Type.u32], vec_type, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/binary/u32_comparison.spec.ts b/src/webgpu/shader/execution/expression/binary/u32_comparison.spec.ts index fbf34b510394..5bb6767b01e0 100644 --- a/src/webgpu/shader/execution/expression/binary/u32_comparison.spec.ts +++ b/src/webgpu/shader/execution/expression/binary/u32_comparison.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the u32 comparison expressions import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeU32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { binary } from './binary.js'; @@ -24,7 +24,7 @@ Expression: x == y ) .fn(async t => { const cases = await d.get('equals'); - await run(t, binary('=='), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('=='), [Type.u32, Type.u32], Type.bool, t.params, cases); }); g.test('not_equals') @@ -39,7 +39,7 @@ Expression: x != y ) .fn(async t => { const cases = await d.get('not_equals'); - await run(t, binary('!='), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('!='), [Type.u32, Type.u32], Type.bool, t.params, cases); }); g.test('less_than') @@ -54,7 +54,7 @@ Expression: x < y ) .fn(async t => { const cases = await d.get('less_than'); - await run(t, binary('<'), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('<'), [Type.u32, Type.u32], Type.bool, t.params, cases); }); g.test('less_equals') @@ -69,7 +69,7 @@ Expression: x <= y ) .fn(async t => { const cases = await d.get('less_equal'); - await run(t, binary('<='), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('<='), [Type.u32, Type.u32], Type.bool, t.params, cases); }); g.test('greater_than') @@ -84,7 +84,7 @@ Expression: x > y ) .fn(async t => { const cases = await d.get('greater_than'); - await run(t, binary('>'), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('>'), [Type.u32, Type.u32], Type.bool, t.params, cases); }); g.test('greater_equals') @@ -99,5 +99,5 @@ Expression: x >= y ) .fn(async t => { const cases = await d.get('greater_equal'); - await run(t, binary('>='), [TypeU32, TypeU32], TypeBool, t.params, cases); + await run(t, binary('>='), [Type.u32, Type.u32], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts index c7f6d1d57cae..75d41ab16377 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/abs.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'abs' builtin function -S is AbstractInt, i32, or u32 +S is abstract-int, i32, or u32 T is S or vecN @const fn abs(e: T ) -> T The absolute value of e. Component-wise when T is a vector. If e is a signed integral scalar type and evaluates to the largest negative value, then the result is e. If e is an unsigned integral type, then the result is e. -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn abs(e: T ) -> T Returns the absolute value of e (e.g. e with a positive sign bit). @@ -18,16 +18,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { kBit } from '../../../../../util/constants.js'; -import { - i32Bits, - TypeF32, - TypeF16, - TypeI32, - TypeU32, - u32Bits, - TypeAbstractFloat, - TypeAbstractInt, -} from '../../../../../util/conversion.js'; +import { Type, i32Bits, u32Bits } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { d } from './abs.cache.js'; @@ -45,7 +36,7 @@ g.test('abstract_int') ) .fn(async t => { const cases = await d.get('abstract_int'); - await run(t, abstractIntBuiltin('abs'), [TypeAbstractInt], TypeAbstractInt, t.params, cases); + await run(t, abstractIntBuiltin('abs'), [Type.abstractInt], Type.abstractInt, t.params, cases); }); g.test('u32') @@ -55,7 +46,7 @@ g.test('u32') u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { - await run(t, builtin('abs'), [TypeU32], TypeU32, t.params, [ + await run(t, builtin('abs'), [Type.u32], Type.u32, t.params, [ // Min and Max u32 { input: u32Bits(kBit.u32.min), expected: u32Bits(kBit.u32.min) }, { input: u32Bits(kBit.u32.max), expected: u32Bits(kBit.u32.max) }, @@ -102,7 +93,7 @@ g.test('i32') u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) ) .fn(async t => { - await run(t, builtin('abs'), [TypeI32], TypeI32, t.params, [ + await run(t, builtin('abs'), [Type.i32], Type.i32, t.params, [ // Min and max i32 // If e evaluates to the largest negative value, then the result is e. { input: i32Bits(kBit.i32.negative.min), expected: i32Bits(kBit.i32.negative.min) }, @@ -158,8 +149,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('abs'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -173,7 +164,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('abs'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('abs'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -187,5 +178,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('abs'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('abs'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts index 1d489e1191b8..7d6b224579a9 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/acos.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'acos' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn acos(e: T ) -> T Returns the arc cosine of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the arc cosine of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './acos.cache.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('acos'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('acos'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('acos'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('acos'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts index 737bd5677241..ed34d326de1a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/acosh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'acosh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn acosh(e: T ) -> T Returns the hyperbolic arc cosine of e. The result is 0 when e < 1. @@ -13,7 +13,7 @@ Note: The result is not mathematically meaningful when e < 1. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './acosh.cache.js'; @@ -37,7 +37,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('acosh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('acosh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -51,5 +51,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('acosh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('acosh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/all.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/all.spec.ts index 9a2938c1d500..74e072703d94 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/all.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/all.spec.ts @@ -10,15 +10,7 @@ Returns true if each component of e is true if e is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - False, - True, - TypeBool, - TypeVec, - vec2, - vec3, - vec4, -} from '../../../../../util/conversion.js'; +import { False, True, Type, vec2, vec3, vec4 } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -36,14 +28,14 @@ g.test('bool') .fn(async t => { const overloads = { scalar: { - type: TypeBool, + type: Type.bool, cases: [ { input: False, expected: False }, { input: True, expected: True }, ], }, vec2: { - type: TypeVec(2, TypeBool), + type: Type.vec(2, Type.bool), cases: [ { input: vec2(False, False), expected: False }, { input: vec2(True, False), expected: False }, @@ -52,7 +44,7 @@ g.test('bool') ], }, vec3: { - type: TypeVec(3, TypeBool), + type: Type.vec(3, Type.bool), cases: [ { input: vec3(False, False, False), expected: False }, { input: vec3(True, False, False), expected: False }, @@ -65,7 +57,7 @@ g.test('bool') ], }, vec4: { - type: TypeVec(4, TypeBool), + type: Type.vec(4, Type.bool), cases: [ { input: vec4(False, False, False, False), expected: False }, { input: vec4(False, True, False, False), expected: False }, @@ -88,5 +80,5 @@ g.test('bool') }; const overload = overloads[t.params.overload]; - await run(t, builtin('all'), [overload.type], TypeBool, t.params, overload.cases); + await run(t, builtin('all'), [overload.type], Type.bool, t.params, overload.cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/any.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/any.spec.ts index 19ed7d186f7b..43c599e2aa4b 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/any.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/any.spec.ts @@ -10,15 +10,7 @@ Returns true if any component of e is true if e is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - False, - True, - TypeBool, - TypeVec, - vec2, - vec3, - vec4, -} from '../../../../../util/conversion.js'; +import { False, True, Type, vec2, vec3, vec4 } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -36,14 +28,14 @@ g.test('bool') .fn(async t => { const overloads = { scalar: { - type: TypeBool, + type: Type.bool, cases: [ { input: False, expected: False }, { input: True, expected: True }, ], }, vec2: { - type: TypeVec(2, TypeBool), + type: Type.vec(2, Type.bool), cases: [ { input: vec2(False, False), expected: False }, { input: vec2(True, False), expected: True }, @@ -52,7 +44,7 @@ g.test('bool') ], }, vec3: { - type: TypeVec(3, TypeBool), + type: Type.vec(3, Type.bool), cases: [ { input: vec3(False, False, False), expected: False }, { input: vec3(True, False, False), expected: True }, @@ -65,7 +57,7 @@ g.test('bool') ], }, vec4: { - type: TypeVec(4, TypeBool), + type: Type.vec(4, Type.bool), cases: [ { input: vec4(False, False, False, False), expected: False }, { input: vec4(False, True, False, False), expected: True }, @@ -88,5 +80,5 @@ g.test('bool') }; const overload = overloads[t.params.overload]; - await run(t, builtin('any'), [overload.type], TypeBool, t.params, overload.cases); + await run(t, builtin('any'), [overload.type], Type.bool, t.params, overload.cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts index 8a7934936030..5ff882d28a34 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/asin.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'asin' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn asin(e: T ) -> T Returns the arc sine of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the arc sine of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './asin.cache.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('asin'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('asin'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('asin'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('asin'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts index b5f362066b85..21f2584cac98 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/asinh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'sinh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn asinh(e: T ) -> T Returns the hyperbolic arc sine of e. @@ -12,7 +12,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './asinh.cache.js'; @@ -36,7 +36,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('asinh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('asinh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -50,5 +50,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('asinh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('asinh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts index 173fb0a0010e..355529eb8dfe 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atan.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'atan' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn atan(e: T ) -> T Returns the arc tangent of e. Component-wise when T is a vector. @@ -10,7 +10,7 @@ Returns the arc tangent of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './atan.cache.js'; @@ -40,7 +40,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('atan'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('atan'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -54,5 +54,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('atan'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('atan'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts index dff1d442f56b..707820c2abdb 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atan2.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'atan2' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn atan2(e1: T ,e2: T ) -> T Returns the arc tangent of e1 over e2. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the arc tangent of e1 over e2. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './atan2.cache.js'; @@ -39,7 +39,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get(`f32_${t.params.inputSource === 'const' ? 'const' : 'non_const'}`); - await run(t, builtin('atan2'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('atan2'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -53,5 +53,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(`f16_${t.params.inputSource === 'const' ? 'const' : 'non_const'}`); - await run(t, builtin('atan2'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('atan2'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts index 31c14110b662..fe43c2161336 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/atanh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'atanh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn atanh(e: T ) -> T Returns the hyperbolic arc tangent of e. The result is 0 when abs(e) ≥ 1. @@ -12,7 +12,7 @@ Note: The result is not mathematically meaningful when abs(e) >= 1. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { d } from './atanh.cache.js'; @@ -36,7 +36,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('atanh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('atanh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -50,5 +50,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('atanh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('atanh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/bitcast.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/bitcast.cache.ts index a3f2ee35b29b..b64d3692121e 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/bitcast.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/bitcast.cache.ts @@ -2,8 +2,8 @@ import { assert } from '../../../../../../common/util/util.js'; import { Comparator, alwaysPass, anyOf } from '../../../../../util/compare.js'; import { kBit, kValue } from '../../../../../util/constants.js'; import { - Scalar, - Vector, + ScalarValue, + VectorValue, f16, f32, i32, @@ -63,7 +63,7 @@ const f32ZerosInterval: FPInterval = new FPInterval('f32', -0.0, 0.0); const f32FiniteRange: number[] = [...scalarF32Range(), kValue.f32.negative.zero]; const f32RangeWithInfAndNaN: number[] = [...f32FiniteRange, ...f32InfAndNaNInF32]; -// F16 values, finite, Inf/NaN, and zeros. Represented in float and u16. +// Type.f16 values, finite, Inf/NaN, and zeros. Represented in float and u16. const f16FiniteInF16: number[] = [...scalarF16Range(), kValue.f16.negative.zero]; const f16FiniteInU16: number[] = f16FiniteInF16.map(u => reinterpretF16AsU16(u)); @@ -118,7 +118,7 @@ function u32ToU16x2(u32: number): number[] { /** * @returns a vec2 from an array of two u16, each reinterpreted as f16. */ -function u16x2ToVec2F16(u16x2: number[]): Vector { +function u16x2ToVec2F16(u16x2: number[]): VectorValue { assert(u16x2.length === 2); return toVector(u16x2.map(reinterpretU16AsF16), f16); } @@ -126,7 +126,7 @@ function u16x2ToVec2F16(u16x2: number[]): Vector { /** * @returns a vec4 from an array of four u16, each reinterpreted as f16. */ -function u16x4ToVec4F16(u16x4: number[]): Vector { +function u16x4ToVec4F16(u16x4: number[]): VectorValue { assert(u16x4.length === 4); return toVector(u16x4.map(reinterpretU16AsF16), f16); } @@ -433,7 +433,7 @@ function bitcastVec2F32ToVec4F16Comparator(f32x2: number[]): Comparator { interface ExpectionFor32BitsScalarFromF16x2 { // possibleExpectations is Scalar array if the expectation is for i32/u32 and FPInterval array for // f32. Note that if the expectation for i32/u32 is unbound, possibleExpectations is meaningless. - possibleExpectations: (Scalar | FPInterval)[]; + possibleExpectations: (ScalarValue | FPInterval)[]; isUnbounded: boolean; } @@ -458,8 +458,8 @@ function possible32BitScalarIntervalsFromF16x2( ): ExpectionFor32BitsScalarFromF16x2 { assert(f16x2InU16x2.length === 2); let reinterpretFromU32: (x: number) => number; - let expectationsForValue: (x: number) => Scalar[] | FPInterval[]; - let unboundedExpectations: FPInterval[] | Scalar[]; + let expectationsForValue: (x: number) => ScalarValue[] | FPInterval[]; + let unboundedExpectations: FPInterval[] | ScalarValue[]; if (type === 'u32') { reinterpretFromU32 = (x: number) => x; expectationsForValue = x => [u32(x)]; @@ -498,12 +498,12 @@ function possible32BitScalarIntervalsFromF16x2( return { possibleExpectations: unboundedExpectations, isUnbounded: true }; } const possibleU16Bits = f16x2InU16x2.map(possibleBitsInU16FromFiniteF16InU16); - const possibleExpectations = cartesianProduct(...possibleU16Bits).flatMap( - (possibleBitsU16x2: readonly number[]) => { - assert(possibleBitsU16x2.length === 2); - return expectationsForValue(reinterpretFromU32(u16x2ToU32(possibleBitsU16x2))); - } - ); + const possibleExpectations = cartesianProduct(...possibleU16Bits).flatMap< + ScalarValue | FPInterval + >((possibleBitsU16x2: readonly number[]) => { + assert(possibleBitsU16x2.length === 2); + return expectationsForValue(reinterpretFromU32(u16x2ToU32(possibleBitsU16x2))); + }); return { possibleExpectations, isUnbounded: false }; } @@ -566,7 +566,7 @@ function bitcastVec4F16ToVec2U32Comparator(vec4F16InU16x4: number[]): Comparator } return anyOf( ...cartesianProduct(...expectationsPerElement.map(e => e.possibleExpectations)).map( - e => new Vector(e as Scalar[]) + e => new VectorValue(e as ScalarValue[]) ) ); } @@ -588,7 +588,7 @@ function bitcastVec4F16ToVec2I32Comparator(vec4F16InU16x4: number[]): Comparator } return anyOf( ...cartesianProduct(...expectationsPerElement.map(e => e.possibleExpectations)).map( - e => new Vector(e as Scalar[]) + e => new VectorValue(e as ScalarValue[]) ) ); } diff --git a/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts index 5e7add44048d..0ead5af05a5b 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/bitcast.spec.ts @@ -11,8 +11,8 @@ S is i32, u32, f32 T is i32, u32, f32, and T is not S Reinterpretation of bits. Beware non-normal f32 values. -@const @must_use fn bitcast(e : AbstractInt) -> T -@const @must_use fn bitcast>(e : vecN) -> T +@const @must_use fn bitcast(e : Type.abstractInt) -> T +@const @must_use fn bitcast>(e : vecN) -> T @const @must_use fn bitcast(e: vec2 ) -> T @const @must_use fn bitcast>(e: vec4 ) -> vec2 @@ -26,18 +26,13 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { anyOf } from '../../../../../util/compare.js'; import { - TypeF16, - TypeF32, - TypeI32, - TypeU32, - TypeVec, - TypeAbstractFloat, f32, u32, i32, abstractFloat, uint32ToFloat32, u32Bits, + Type, } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; import { scalarF32Range } from '../../../../../util/math.js'; @@ -76,7 +71,7 @@ g.test('i32_to_i32') ) .fn(async t => { const cases = await d.get('i32_to_i32'); - await run(t, bitcastBuilder('i32', t.params), [TypeI32], TypeI32, t.params, cases); + await run(t, bitcastBuilder('i32', t.params), [Type.i32], Type.i32, t.params, cases); }); g.test('u32_to_u32') @@ -90,7 +85,7 @@ g.test('u32_to_u32') ) .fn(async t => { const cases = await d.get('u32_to_u32'); - await run(t, bitcastBuilder('u32', t.params), [TypeU32], TypeU32, t.params, cases); + await run(t, bitcastBuilder('u32', t.params), [Type.u32], Type.u32, t.params, cases); }); g.test('f32_to_f32') @@ -107,7 +102,7 @@ g.test('f32_to_f32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'f32_to_f32' : 'f32_inf_nan_to_f32' ); - await run(t, bitcastBuilder('f32', t.params), [TypeF32], TypeF32, t.params, cases); + await run(t, bitcastBuilder('f32', t.params), [Type.f32], Type.f32, t.params, cases); }); // To i32 from u32, f32 @@ -122,7 +117,7 @@ g.test('u32_to_i32') ) .fn(async t => { const cases = await d.get('u32_to_i32'); - await run(t, bitcastBuilder('i32', t.params), [TypeU32], TypeI32, t.params, cases); + await run(t, bitcastBuilder('i32', t.params), [Type.u32], Type.i32, t.params, cases); }); g.test('f32_to_i32') @@ -139,7 +134,7 @@ g.test('f32_to_i32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'f32_to_i32' : 'f32_inf_nan_to_i32' ); - await run(t, bitcastBuilder('i32', t.params), [TypeF32], TypeI32, t.params, cases); + await run(t, bitcastBuilder('i32', t.params), [Type.f32], Type.i32, t.params, cases); }); // To u32 from i32, f32 @@ -154,7 +149,7 @@ g.test('i32_to_u32') ) .fn(async t => { const cases = await d.get('i32_to_u32'); - await run(t, bitcastBuilder('u32', t.params), [TypeI32], TypeU32, t.params, cases); + await run(t, bitcastBuilder('u32', t.params), [Type.i32], Type.u32, t.params, cases); }); g.test('f32_to_u32') @@ -171,7 +166,7 @@ g.test('f32_to_u32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'f32_to_u32' : 'f32_inf_nan_to_u32' ); - await run(t, bitcastBuilder('u32', t.params), [TypeF32], TypeU32, t.params, cases); + await run(t, bitcastBuilder('u32', t.params), [Type.f32], Type.u32, t.params, cases); }); // To f32 from i32, u32 @@ -189,7 +184,7 @@ g.test('i32_to_f32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'i32_to_f32' : 'i32_to_f32_inf_nan' ); - await run(t, bitcastBuilder('f32', t.params), [TypeI32], TypeF32, t.params, cases); + await run(t, bitcastBuilder('f32', t.params), [Type.i32], Type.f32, t.params, cases); }); g.test('u32_to_f32') @@ -206,7 +201,7 @@ g.test('u32_to_f32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'u32_to_f32' : 'u32_to_f32_inf_nan' ); - await run(t, bitcastBuilder('f32', t.params), [TypeU32], TypeF32, t.params, cases); + await run(t, bitcastBuilder('f32', t.params), [Type.u32], Type.f32, t.params, cases); }); // 16 bit types @@ -231,7 +226,7 @@ g.test('f16_to_f16') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'f16_to_f16' : 'f16_inf_nan_to_f16' ); - await run(t, bitcastBuilder('f16', t.params), [TypeF16], TypeF16, t.params, cases); + await run(t, bitcastBuilder('f16', t.params), [Type.f16], Type.f16, t.params, cases); }); // f16: 32-bit scalar numeric to vec2 @@ -247,14 +242,7 @@ g.test('i32_to_vec2h') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'i32_to_vec2_f16' : 'i32_to_vec2_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeI32], - TypeVec(2, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.i32], Type.vec2h, t.params, cases); }); g.test('u32_to_vec2h') @@ -269,14 +257,7 @@ g.test('u32_to_vec2h') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'u32_to_vec2_f16' : 'u32_to_vec2_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeU32], - TypeVec(2, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.u32], Type.vec2h, t.params, cases); }); g.test('f32_to_vec2h') @@ -291,14 +272,7 @@ g.test('f32_to_vec2h') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'f32_to_vec2_f16' : 'f32_inf_nan_to_vec2_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeF32], - TypeVec(2, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.f32], Type.vec2h, t.params, cases); }); // f16: vec2<32-bit scalar numeric> to vec4 @@ -314,14 +288,7 @@ g.test('vec2i_to_vec4h') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec2_i32_to_vec4_f16' : 'vec2_i32_to_vec4_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec4', t.params), - [TypeVec(2, TypeI32)], - TypeVec(4, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec4', t.params), [Type.vec2i], Type.vec4h, t.params, cases); }); g.test('vec2u_to_vec4h') @@ -336,14 +303,7 @@ g.test('vec2u_to_vec4h') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec2_u32_to_vec4_f16' : 'vec2_u32_to_vec4_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec4', t.params), - [TypeVec(2, TypeU32)], - TypeVec(4, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec4', t.params), [Type.vec2u], Type.vec4h, t.params, cases); }); g.test('vec2f_to_vec4h') @@ -360,14 +320,7 @@ g.test('vec2f_to_vec4h') ? 'vec2_f32_to_vec4_f16' : 'vec2_f32_inf_nan_to_vec4_f16_inf_nan' ); - await run( - t, - bitcastBuilder('vec4', t.params), - [TypeVec(2, TypeF32)], - TypeVec(4, TypeF16), - t.params, - cases - ); + await run(t, bitcastBuilder('vec4', t.params), [Type.vec2f], Type.vec4h, t.params, cases); }); // f16: vec2 to 32-bit scalar numeric @@ -383,7 +336,7 @@ g.test('vec2h_to_i32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec2_f16_to_i32' : 'vec2_f16_inf_nan_to_i32' ); - await run(t, bitcastBuilder('i32', t.params), [TypeVec(2, TypeF16)], TypeI32, t.params, cases); + await run(t, bitcastBuilder('i32', t.params), [Type.vec2h], Type.i32, t.params, cases); }); g.test('vec2h_to_u32') @@ -398,7 +351,7 @@ g.test('vec2h_to_u32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec2_f16_to_u32' : 'vec2_f16_inf_nan_to_u32' ); - await run(t, bitcastBuilder('u32', t.params), [TypeVec(2, TypeF16)], TypeU32, t.params, cases); + await run(t, bitcastBuilder('u32', t.params), [Type.vec2h], Type.u32, t.params, cases); }); g.test('vec2h_to_f32') @@ -413,7 +366,7 @@ g.test('vec2h_to_f32') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec2_f16_to_f32_finite' : 'vec2_f16_inf_nan_to_f32' ); - await run(t, bitcastBuilder('f32', t.params), [TypeVec(2, TypeF16)], TypeF32, t.params, cases); + await run(t, bitcastBuilder('f32', t.params), [Type.vec2h], Type.f32, t.params, cases); }); // f16: vec4 to vec2<32-bit scalar numeric> @@ -429,14 +382,7 @@ g.test('vec4h_to_vec2i') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec4_f16_to_vec2_i32' : 'vec4_f16_inf_nan_to_vec2_i32' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeVec(4, TypeF16)], - TypeVec(2, TypeI32), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.vec4h], Type.vec2i, t.params, cases); }); g.test('vec4h_to_vec2u') @@ -451,14 +397,7 @@ g.test('vec4h_to_vec2u') // Infinities and NaNs are errors in const-eval. t.params.inputSource === 'const' ? 'vec4_f16_to_vec2_u32' : 'vec4_f16_inf_nan_to_vec2_u32' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeVec(4, TypeF16)], - TypeVec(2, TypeU32), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.vec4h], Type.vec2u, t.params, cases); }); g.test('vec4h_to_vec2f') @@ -475,14 +414,7 @@ g.test('vec4h_to_vec2f') ? 'vec4_f16_to_vec2_f32_finite' : 'vec4_f16_inf_nan_to_vec2_f32' ); - await run( - t, - bitcastBuilder('vec2', t.params), - [TypeVec(4, TypeF16)], - TypeVec(2, TypeF32), - t.params, - cases - ); + await run(t, bitcastBuilder('vec2', t.params), [Type.vec4h], Type.vec2f, t.params, cases); }); // Abstract Float @@ -505,7 +437,7 @@ g.test('af_to_f32') }; }); - await run(t, bitcastBuilder('f32', t.params), [TypeAbstractFloat], TypeF32, t.params, cases); + await run(t, bitcastBuilder('f32', t.params), [Type.abstractFloat], Type.f32, t.params, cases); }); g.test('af_to_i32') @@ -522,24 +454,24 @@ g.test('af_to_i32') 1, 10, 256, - u32Bits(0b11111111011111111111111111111111).value as number, - u32Bits(0b11111111010000000000000000000000).value as number, - u32Bits(0b11111110110000000000000000000000).value as number, - u32Bits(0b11111101110000000000000000000000).value as number, - u32Bits(0b11111011110000000000000000000000).value as number, - u32Bits(0b11110111110000000000000000000000).value as number, - u32Bits(0b11101111110000000000000000000000).value as number, - u32Bits(0b11011111110000000000000000000000).value as number, - u32Bits(0b10111111110000000000000000000000).value as number, - u32Bits(0b01111111011111111111111111111111).value as number, - u32Bits(0b01111111010000000000000000000000).value as number, - u32Bits(0b01111110110000000000000000000000).value as number, - u32Bits(0b01111101110000000000000000000000).value as number, - u32Bits(0b01111011110000000000000000000000).value as number, - u32Bits(0b01110111110000000000000000000000).value as number, - u32Bits(0b01101111110000000000000000000000).value as number, - u32Bits(0b01011111110000000000000000000000).value as number, - u32Bits(0b00111111110000000000000000000000).value as number, + u32Bits(0b11111111011111111111111111111111).value, + u32Bits(0b11111111010000000000000000000000).value, + u32Bits(0b11111110110000000000000000000000).value, + u32Bits(0b11111101110000000000000000000000).value, + u32Bits(0b11111011110000000000000000000000).value, + u32Bits(0b11110111110000000000000000000000).value, + u32Bits(0b11101111110000000000000000000000).value, + u32Bits(0b11011111110000000000000000000000).value, + u32Bits(0b10111111110000000000000000000000).value, + u32Bits(0b01111111011111111111111111111111).value, + u32Bits(0b01111111010000000000000000000000).value, + u32Bits(0b01111110110000000000000000000000).value, + u32Bits(0b01111101110000000000000000000000).value, + u32Bits(0b01111011110000000000000000000000).value, + u32Bits(0b01110111110000000000000000000000).value, + u32Bits(0b01101111110000000000000000000000).value, + u32Bits(0b01011111110000000000000000000000).value, + u32Bits(0b00111111110000000000000000000000).value, ]; const cases = values.map(u => { @@ -549,7 +481,7 @@ g.test('af_to_i32') }; }); - await run(t, bitcastBuilder('i32', t.params), [TypeAbstractFloat], TypeI32, t.params, cases); + await run(t, bitcastBuilder('i32', t.params), [Type.abstractFloat], Type.i32, t.params, cases); }); g.test('af_to_u32') @@ -566,24 +498,24 @@ g.test('af_to_u32') 1, 10, 256, - u32Bits(0b11111111011111111111111111111111).value as number, - u32Bits(0b11111111010000000000000000000000).value as number, - u32Bits(0b11111110110000000000000000000000).value as number, - u32Bits(0b11111101110000000000000000000000).value as number, - u32Bits(0b11111011110000000000000000000000).value as number, - u32Bits(0b11110111110000000000000000000000).value as number, - u32Bits(0b11101111110000000000000000000000).value as number, - u32Bits(0b11011111110000000000000000000000).value as number, - u32Bits(0b10111111110000000000000000000000).value as number, - u32Bits(0b01111111011111111111111111111111).value as number, - u32Bits(0b01111111010000000000000000000000).value as number, - u32Bits(0b01111110110000000000000000000000).value as number, - u32Bits(0b01111101110000000000000000000000).value as number, - u32Bits(0b01111011110000000000000000000000).value as number, - u32Bits(0b01110111110000000000000000000000).value as number, - u32Bits(0b01101111110000000000000000000000).value as number, - u32Bits(0b01011111110000000000000000000000).value as number, - u32Bits(0b00111111110000000000000000000000).value as number, + u32Bits(0b11111111011111111111111111111111).value, + u32Bits(0b11111111010000000000000000000000).value, + u32Bits(0b11111110110000000000000000000000).value, + u32Bits(0b11111101110000000000000000000000).value, + u32Bits(0b11111011110000000000000000000000).value, + u32Bits(0b11110111110000000000000000000000).value, + u32Bits(0b11101111110000000000000000000000).value, + u32Bits(0b11011111110000000000000000000000).value, + u32Bits(0b10111111110000000000000000000000).value, + u32Bits(0b01111111011111111111111111111111).value, + u32Bits(0b01111111010000000000000000000000).value, + u32Bits(0b01111110110000000000000000000000).value, + u32Bits(0b01111101110000000000000000000000).value, + u32Bits(0b01111011110000000000000000000000).value, + u32Bits(0b01110111110000000000000000000000).value, + u32Bits(0b01101111110000000000000000000000).value, + u32Bits(0b01011111110000000000000000000000).value, + u32Bits(0b00111111110000000000000000000000).value, ]; const cases = values.map(u => { @@ -593,7 +525,7 @@ g.test('af_to_u32') }; }); - await run(t, bitcastBuilder('u32', t.params), [TypeAbstractFloat], TypeU32, t.params, cases); + await run(t, bitcastBuilder('u32', t.params), [Type.abstractFloat], Type.u32, t.params, cases); }); g.test('af_to_vec2f16') @@ -609,8 +541,8 @@ g.test('af_to_vec2f16') await run( t, bitcastBuilder('vec2', t.params), - [TypeAbstractFloat], - TypeVec(2, TypeF16), + [Type.abstractFloat], + Type.vec2h, t.params, cases ); @@ -629,8 +561,8 @@ g.test('vec2af_to_vec4f16') await run( t, bitcastBuilder('vec4', t.params), - [TypeVec(2, TypeAbstractFloat)], - TypeVec(4, TypeF16), + [Type.vec(2, Type.abstractFloat)], + Type.vec4h, t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts index 18509efdffb9..5f6236149e53 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/ceil.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'ceil' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn ceil(e: T ) -> T Returns the ceiling of e. Component-wise when T is a vector. @@ -10,7 +10,7 @@ Returns the ceiling of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -34,7 +34,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('ceil'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('ceil'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -48,5 +48,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('ceil'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('ceil'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/clamp.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/clamp.cache.ts index ef63fb385ba5..909d15e7e752 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/clamp.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/clamp.cache.ts @@ -1,5 +1,5 @@ import { kValue } from '../../../../../util/constants.js'; -import { ScalarType, TypeAbstractInt, TypeI32, TypeU32 } from '../../../../../util/conversion.js'; +import { ScalarType, Type } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; import { maxBigInt, minBigInt } from '../../../../../util/math.js'; import { Case } from '../../case.js'; @@ -59,11 +59,11 @@ function generateAbstractIntegerTestCases(test_values: Array): Array ({ input: [ - TypeAbstractInt.create(e), - TypeAbstractInt.create(low), - TypeAbstractInt.create(high), + Type.abstractInt.create(e), + Type.abstractInt.create(low), + Type.abstractInt.create(high), ], - expected: TypeAbstractInt.create(minBigInt(maxBigInt(e, low), high)), + expected: Type.abstractInt.create(minBigInt(maxBigInt(e, low), high)), })) ) ); @@ -113,16 +113,16 @@ const fp_cases = (['f32', 'f16', 'abstract'] as const) export const d = makeCaseCache('clamp', { u32_non_const: () => { - return generateConcreteIntegerTestCases(u32Values, TypeU32, 'non_const'); + return generateConcreteIntegerTestCases(u32Values, Type.u32, 'non_const'); }, u32_const: () => { - return generateConcreteIntegerTestCases(u32Values, TypeU32, 'const'); + return generateConcreteIntegerTestCases(u32Values, Type.u32, 'const'); }, i32_non_const: () => { - return generateConcreteIntegerTestCases(i32Values, TypeI32, 'non_const'); + return generateConcreteIntegerTestCases(i32Values, Type.i32, 'non_const'); }, i32_const: () => { - return generateConcreteIntegerTestCases(i32Values, TypeI32, 'const'); + return generateConcreteIntegerTestCases(i32Values, Type.i32, 'const'); }, abstract_int: () => { return generateAbstractIntegerTestCases(abstractFloatValues); diff --git a/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts index cc29ceba03f7..0b524bccf0d3 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/clamp.spec.ts @@ -1,12 +1,12 @@ export const description = ` Execution tests for the 'clamp' builtin function -S is AbstractInt, i32, or u32 +S is abstract-int, i32, or u32 T is S or vecN @const fn clamp(e: T , low: T, high: T) -> T Returns min(max(e,low),high). Component-wise when T is a vector. -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const clamp(e: T , low: T , high: T) -> T Returns either min(max(e,low),high), or the median of the three values e, low, high. @@ -15,14 +15,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - TypeAbstractFloat, - TypeAbstractInt, - TypeF16, - TypeF32, - TypeI32, - TypeU32, -} from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, abstractIntBuiltin, builtin } from './builtin.js'; @@ -43,8 +36,8 @@ g.test('abstract_int') await run( t, abstractIntBuiltin('clamp'), - [TypeAbstractInt, TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -58,7 +51,7 @@ g.test('u32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('clamp'), [TypeU32, TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, builtin('clamp'), [Type.u32, Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('i32') @@ -69,7 +62,7 @@ g.test('i32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'i32_const' : 'i32_non_const'); - await run(t, builtin('clamp'), [TypeI32, TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, builtin('clamp'), [Type.i32, Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('abstract_float') @@ -85,8 +78,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('clamp'), - [TypeAbstractFloat, TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -100,7 +93,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('clamp'), [TypeF32, TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('clamp'), [Type.f32, Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -114,5 +107,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('clamp'), [TypeF16, TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('clamp'), [Type.f16, Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts index 5eb9081928d1..4e3756834def 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cos.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'cos' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn cos(e: T ) -> T Returns the cosine of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the cosine of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -39,7 +39,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('cos'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('cos'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -53,5 +53,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('cos'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('cos'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts index aba7212a06e3..70713a392751 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cosh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'cosh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn cosh(e: T ) -> T Returns the hyperbolic cosine of e. Component-wise when T is a vector @@ -9,7 +9,7 @@ Returns the hyperbolic cosine of e. Component-wise when T is a vector import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('cosh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('cosh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('cosh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('cosh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/countLeadingZeros.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/countLeadingZeros.spec.ts index cfae4bb6e03b..ea0c38ae58d9 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/countLeadingZeros.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/countLeadingZeros.spec.ts @@ -12,7 +12,7 @@ Also known as "clz" in some languages. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, u32Bits, u32, TypeI32, i32Bits, i32 } from '../../../../../util/conversion.js'; +import { Type, u32Bits, u32, i32Bits, i32 } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -27,7 +27,7 @@ g.test('u32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countLeadingZeros'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('countLeadingZeros'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32(32) }, @@ -142,7 +142,7 @@ g.test('i32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countLeadingZeros'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('countLeadingZeros'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32(32) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/countOneBits.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/countOneBits.spec.ts index f0be9162856a..1937e0428362 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/countOneBits.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/countOneBits.spec.ts @@ -11,7 +11,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, u32Bits, u32, TypeI32, i32Bits, i32 } from '../../../../../util/conversion.js'; +import { Type, u32Bits, u32, i32Bits, i32 } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -26,7 +26,7 @@ g.test('u32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countOneBits'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('countOneBits'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32(0) }, @@ -141,7 +141,7 @@ g.test('i32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countOneBits'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('countOneBits'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32(0) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/countTrailingZeros.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/countTrailingZeros.spec.ts index d0b3198f49c4..3392a47810cf 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/countTrailingZeros.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/countTrailingZeros.spec.ts @@ -12,7 +12,7 @@ Also known as "ctz" in some languages. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { i32, i32Bits, TypeI32, u32, TypeU32, u32Bits } from '../../../../../util/conversion.js'; +import { i32, i32Bits, Type, u32, u32Bits } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -27,7 +27,7 @@ g.test('u32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countTrailingZeros'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('countTrailingZeros'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32(32) }, @@ -142,7 +142,7 @@ g.test('i32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('countTrailingZeros'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('countTrailingZeros'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32(32) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/cross.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/cross.spec.ts index 95b39f45c5b3..cc32537076d1 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/cross.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/cross.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'cross' builtin function -T is AbstractFloat, f32, or f16 +T is abstract-float, f32, or f16 @const fn cross(e1: vec3 ,e2: vec3) -> vec3 Returns the cross product of e1 and e2. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -25,8 +25,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('cross'), - [TypeVec(3, TypeAbstractFloat), TypeVec(3, TypeAbstractFloat)], - TypeVec(3, TypeAbstractFloat), + [Type.vec(3, Type.abstractFloat), Type.vec(3, Type.abstractFloat)], + Type.vec(3, Type.abstractFloat), t.params, cases ); @@ -38,14 +38,7 @@ g.test('f32') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run( - t, - builtin('cross'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32)], - TypeVec(3, TypeF32), - t.params, - cases - ); + await run(t, builtin('cross'), [Type.vec3f, Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f16') @@ -57,12 +50,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run( - t, - builtin('cross'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16)], - TypeVec(3, TypeF16), - t.params, - cases - ); + await run(t, builtin('cross'), [Type.vec3h, Type.vec3h], Type.vec3h, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts index f69a92cf5f45..e8589c99332d 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/degrees.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'degrees' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn degrees(e1: T ) -> T Converts radians to degrees, approximating e1 × 180 ÷ π. Component-wise when T is a vector @@ -9,7 +9,7 @@ Converts radians to degrees, approximating e1 × 180 ÷ π. Component-wise when import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -30,8 +30,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('degrees'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -45,7 +45,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('degrees'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('degrees'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -59,5 +59,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('degrees'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('degrees'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/determinant.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/determinant.spec.ts index c628623f4378..8b259eedb33e 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/determinant.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/determinant.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'determinant' builtin function -T is AbstractFloat, f32, or f16 +T is abstract-float, f32, or f16 @const determinant(e: matCxC ) -> T Returns the determinant of e. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeMat } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ? `f32_mat${dim}x${dim}_const` : `f32_mat${dim}x${dim}_non_const` ); - await run(t, builtin('determinant'), [TypeMat(dim, dim, TypeF32)], TypeF32, t.params, cases); + await run(t, builtin('determinant'), [Type.mat(dim, dim, Type.f32)], Type.f32, t.params, cases); }); g.test('f16') @@ -50,5 +50,5 @@ g.test('f16') ? `f16_mat${dim}x${dim}_const` : `f16_mat${dim}x${dim}_non_const` ); - await run(t, builtin('determinant'), [TypeMat(dim, dim, TypeF16)], TypeF16, t.params, cases); + await run(t, builtin('determinant'), [Type.mat(dim, dim, Type.f16)], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts index ab63029ca227..0f50cd30d37a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/distance.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'distance' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn distance(e1: T ,e2: T ) -> f32 Returns the distance between e1 and e2 (e.g. length(e1-e2)). @@ -10,7 +10,7 @@ Returns the distance between e1 and e2 (e.g. length(e1-e2)). import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -32,7 +32,7 @@ g.test('f32') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('distance'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('distance'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f32_vec2') @@ -43,14 +43,7 @@ g.test('f32_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_const' : 'f32_vec2_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec2f, Type.vec2f], Type.f32, t.params, cases); }); g.test('f32_vec3') @@ -61,14 +54,7 @@ g.test('f32_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_const' : 'f32_vec3_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec3f, Type.vec3f], Type.f32, t.params, cases); }); g.test('f32_vec4') @@ -79,14 +65,7 @@ g.test('f32_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_const' : 'f32_vec4_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec4f, Type.vec4f], Type.f32, t.params, cases); }); g.test('f16') @@ -98,7 +77,7 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('distance'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('distance'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('f16_vec2') @@ -112,14 +91,7 @@ g.test('f16_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_const' : 'f16_vec2_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec2h, Type.vec2h], Type.f16, t.params, cases); }); g.test('f16_vec3') @@ -133,14 +105,7 @@ g.test('f16_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_const' : 'f16_vec3_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec3h, Type.vec3h], Type.f16, t.params, cases); }); g.test('f16_vec4') @@ -154,12 +119,5 @@ g.test('f16_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_const' : 'f16_vec4_non_const' ); - await run( - t, - builtin('distance'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('distance'), [Type.vec4h, Type.vec4h], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/dot.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/dot.spec.ts index 5d27e5044dea..7d39aa0fbe25 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/dot.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/dot.spec.ts @@ -1,21 +1,14 @@ export const description = ` Execution tests for the 'dot' builtin function -T is AbstractInt, AbstractFloat, i32, u32, f32, or f16 +T is Type.abstractInt, Type.abstractFloat, i32, u32, f32, or f16 @const fn dot(e1: vecN,e2: vecN) -> T Returns the dot product of e1 and e2. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - TypeAbstractInt, - TypeF16, - TypeF32, - TypeI32, - TypeU32, - TypeVec, -} from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractIntBuiltin, builtin } from './builtin.js'; @@ -32,8 +25,8 @@ g.test('abstract_int_vec2') await run( t, abstractIntBuiltin('dot'), - [TypeVec(2, TypeAbstractInt), TypeVec(2, TypeAbstractInt)], - TypeAbstractInt, + [Type.vec(2, Type.abstractInt), Type.vec(2, Type.abstractInt)], + Type.abstractInt, t.params, cases ); @@ -48,8 +41,8 @@ g.test('abstract_int_vec3') await run( t, abstractIntBuiltin('dot'), - [TypeVec(3, TypeAbstractInt), TypeVec(3, TypeAbstractInt)], - TypeAbstractInt, + [Type.vec(3, Type.abstractInt), Type.vec(3, Type.abstractInt)], + Type.abstractInt, t.params, cases ); @@ -64,8 +57,8 @@ g.test('abstract_int_vec4') await run( t, abstractIntBuiltin('dot'), - [TypeVec(4, TypeAbstractInt), TypeVec(4, TypeAbstractInt)], - TypeAbstractInt, + [Type.vec(4, Type.abstractInt), Type.vec(4, Type.abstractInt)], + Type.abstractInt, t.params, cases ); @@ -77,14 +70,7 @@ g.test('i32_vec2') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('i32_vec2'); - await run( - t, - builtin('dot'), - [TypeVec(2, TypeI32), TypeVec(2, TypeI32)], - TypeI32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec2i, Type.vec2i], Type.i32, t.params, cases); }); g.test('i32_vec3') @@ -93,14 +79,7 @@ g.test('i32_vec3') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('i32_vec3'); - await run( - t, - builtin('dot'), - [TypeVec(3, TypeI32), TypeVec(3, TypeI32)], - TypeI32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec3i, Type.vec3i], Type.i32, t.params, cases); }); g.test('i32_vec4') @@ -109,14 +88,7 @@ g.test('i32_vec4') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('i32_vec4'); - await run( - t, - builtin('dot'), - [TypeVec(4, TypeI32), TypeVec(4, TypeI32)], - TypeI32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec4i, Type.vec4i], Type.i32, t.params, cases); }); g.test('u32_vec2') @@ -125,14 +97,7 @@ g.test('u32_vec2') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('u32_vec2'); - await run( - t, - builtin('dot'), - [TypeVec(2, TypeU32), TypeVec(2, TypeU32)], - TypeU32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec2u, Type.vec2u], Type.u32, t.params, cases); }); g.test('u32_vec3') @@ -141,14 +106,7 @@ g.test('u32_vec3') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('u32_vec3'); - await run( - t, - builtin('dot'), - [TypeVec(3, TypeU32), TypeVec(3, TypeU32)], - TypeU32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec3u, Type.vec3u], Type.u32, t.params, cases); }); g.test('u32_vec4') @@ -157,14 +115,7 @@ g.test('u32_vec4') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('u32_vec4'); - await run( - t, - builtin('dot'), - [TypeVec(4, TypeU32), TypeVec(4, TypeU32)], - TypeU32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec4u, Type.vec4u], Type.u32, t.params, cases); }); g.test('abstract_float') @@ -181,14 +132,7 @@ g.test('f32_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_const' : 'f32_vec2_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec2f, Type.vec2f], Type.f32, t.params, cases); }); g.test('f32_vec3') @@ -199,14 +143,7 @@ g.test('f32_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_const' : 'f32_vec3_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec3f, Type.vec3f], Type.f32, t.params, cases); }); g.test('f32_vec4') @@ -217,14 +154,7 @@ g.test('f32_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_const' : 'f32_vec4_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32)], - TypeF32, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec4f, Type.vec4f], Type.f32, t.params, cases); }); g.test('f16_vec2') @@ -238,14 +168,7 @@ g.test('f16_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_const' : 'f16_vec2_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec2h, Type.vec2h], Type.f16, t.params, cases); }); g.test('f16_vec3') @@ -259,14 +182,7 @@ g.test('f16_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_const' : 'f16_vec3_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec3h, Type.vec3h], Type.f16, t.params, cases); }); g.test('f16_vec4') @@ -280,12 +196,5 @@ g.test('f16_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_const' : 'f16_vec4_non_const' ); - await run( - t, - builtin('dot'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16)], - TypeF16, - t.params, - cases - ); + await run(t, builtin('dot'), [Type.vec4h, Type.vec4h], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/dot4I8Packed.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/dot4I8Packed.spec.ts index dee5290281a8..de537c473e64 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/dot4I8Packed.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/dot4I8Packed.spec.ts @@ -9,7 +9,7 @@ the multiply, and then the add operations are done in WGSL i32 with wrapping beh import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeI32, TypeU32, i32, u32 } from '../../../../../util/conversion.js'; +import { Type, i32, u32 } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -70,5 +70,5 @@ g.test('basic') return [makeCase(...(v as [number, number]))]; }); - await run(t, builtin('dot4I8Packed'), [TypeU32, TypeU32], TypeI32, cfg, cases); + await run(t, builtin('dot4I8Packed'), [Type.u32, Type.u32], Type.i32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/dot4U8Packed.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/dot4U8Packed.spec.ts index f0dd6fc5081b..a12a3d012302 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/dot4U8Packed.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/dot4U8Packed.spec.ts @@ -8,7 +8,7 @@ unsigned integer dot product of these two vectors. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, u32 } from '../../../../../util/conversion.js'; +import { Type, u32 } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -55,5 +55,5 @@ g.test('basic') return [makeCase(...(v as [number, number]))]; }); - await run(t, builtin('dot4U8Packed'), [TypeU32, TypeU32], TypeU32, cfg, cases); + await run(t, builtin('dot4U8Packed'), [Type.u32, Type.u32], Type.u32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/exp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/exp.spec.ts index ad381df01690..09759ea190ef 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/exp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/exp.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'exp' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn exp(e1: T ) -> T Returns the natural exponentiation of e1 (e.g. e^e1). Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the natural exponentiation of e1 (e.g. e^e1). Component-wise when T is a import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('exp'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('exp'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('exp'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('exp'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/exp2.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/exp2.spec.ts index cf0e3c3cbe81..f6b00c47ecca 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/exp2.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/exp2.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'exp2' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn exp2(e: T ) -> T Returns 2 raised to the power e (e.g. 2^e). Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns 2 raised to the power e (e.g. 2^e). Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('exp2'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('exp2'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('exp2'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('exp2'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/extractBits.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/extractBits.spec.ts index d535bf5d746a..ef04b661bddf 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/extractBits.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/extractBits.spec.ts @@ -33,17 +33,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - i32Bits, - TypeI32, - u32, - TypeU32, - u32Bits, - vec2, - vec3, - vec4, - TypeVec, -} from '../../../../../util/conversion.js'; +import { i32Bits, Type, u32, u32Bits, vec2, vec3, vec4 } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -57,7 +47,7 @@ g.test('u32') .fn(async t => { const cfg: Config = t.params; - const T = t.params.width === 1 ? TypeU32 : TypeVec(t.params.width, TypeU32); + const T = t.params.width === 1 ? Type.u32 : Type.vec(t.params.width, Type.u32); const V = (x: number, y?: number, z?: number, w?: number) => { y = y === undefined ? x : y; @@ -193,7 +183,7 @@ g.test('u32') ); } - await run(t, builtin('extractBits'), [T, TypeU32, TypeU32], T, cfg, cases); + await run(t, builtin('extractBits'), [T, Type.u32, Type.u32], T, cfg, cases); }); g.test('i32') @@ -203,7 +193,7 @@ g.test('i32') .fn(async t => { const cfg: Config = t.params; - const T = t.params.width === 1 ? TypeI32 : TypeVec(t.params.width, TypeI32); + const T = t.params.width === 1 ? Type.i32 : Type.vec(t.params.width, Type.i32); const V = (x: number, y?: number, z?: number, w?: number) => { y = y === undefined ? x : y; @@ -333,5 +323,5 @@ g.test('i32') ); } - await run(t, builtin('extractBits'), [T, TypeU32, TypeU32], T, cfg, cases); + await run(t, builtin('extractBits'), [T, Type.u32, Type.u32], T, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/faceForward.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/faceForward.spec.ts index c21541ab8839..fae851439fc9 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/faceForward.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/faceForward.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'faceForward' builtin function -T is vecN, vecN, or vecN +T is vecN, vecN, or vecN @const fn faceForward(e1: T ,e2: T ,e3: T ) -> T Returns e1 if dot(e2,e3) is negative, and -e1 otherwise. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,8 +33,8 @@ g.test('f32_vec2') await run( t, builtin('faceForward'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32), TypeVec(2, TypeF32)], - TypeVec(2, TypeF32), + [Type.vec2f, Type.vec2f, Type.vec2f], + Type.vec2f, t.params, cases ); @@ -51,8 +51,8 @@ g.test('f32_vec3') await run( t, builtin('faceForward'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32), TypeVec(3, TypeF32)], - TypeVec(3, TypeF32), + [Type.vec3f, Type.vec3f, Type.vec3f], + Type.vec3f, t.params, cases ); @@ -69,8 +69,8 @@ g.test('f32_vec4') await run( t, builtin('faceForward'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32), TypeVec(4, TypeF32)], - TypeVec(4, TypeF32), + [Type.vec4f, Type.vec4f, Type.vec4f], + Type.vec4f, t.params, cases ); @@ -90,8 +90,8 @@ g.test('f16_vec2') await run( t, builtin('faceForward'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16), TypeVec(2, TypeF16)], - TypeVec(2, TypeF16), + [Type.vec2h, Type.vec2h, Type.vec2h], + Type.vec2h, t.params, cases ); @@ -111,8 +111,8 @@ g.test('f16_vec3') await run( t, builtin('faceForward'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16), TypeVec(3, TypeF16)], - TypeVec(3, TypeF16), + [Type.vec3h, Type.vec3h, Type.vec3h], + Type.vec3h, t.params, cases ); @@ -132,8 +132,8 @@ g.test('f16_vec4') await run( t, builtin('faceForward'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16), TypeVec(4, TypeF16)], - TypeVec(4, TypeF16), + [Type.vec4h, Type.vec4h, Type.vec4h], + Type.vec4h, t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/call/builtin/firstLeadingBit.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/firstLeadingBit.spec.ts index 26216563cd04..9248b1e2bf5c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/firstLeadingBit.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/firstLeadingBit.spec.ts @@ -16,7 +16,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { i32, i32Bits, TypeI32, u32, TypeU32, u32Bits } from '../../../../../util/conversion.js'; +import { i32, i32Bits, Type, u32, u32Bits } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -31,7 +31,7 @@ g.test('u32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('firstLeadingBit'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('firstLeadingBit'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32(-1) }, @@ -146,7 +146,7 @@ g.test('i32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('firstLeadingBit'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('firstLeadingBit'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32(-1) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/firstTrailingBit.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/firstTrailingBit.spec.ts index 5c65f59d2813..a8dd27ee87b2 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/firstTrailingBit.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/firstTrailingBit.spec.ts @@ -12,7 +12,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { i32, i32Bits, TypeI32, u32, TypeU32, u32Bits } from '../../../../../util/conversion.js'; +import { i32, i32Bits, Type, u32, u32Bits } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -27,7 +27,7 @@ g.test('u32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('firstTrailingBit'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('firstTrailingBit'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32(-1) }, @@ -142,7 +142,7 @@ g.test('i32') ) .fn(async t => { const cfg: Config = t.params; - await run(t, builtin('firstTrailingBit'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('firstTrailingBit'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32(-1) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts index 63b0a138a045..26cffe5d10da 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/floor.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'floor' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn floor(e: T ) -> T Returns the floor of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the floor of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -30,8 +30,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('floor'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -45,7 +45,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('floor'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('floor'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -59,5 +59,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('floor'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('floor'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts index 2488603d8077..620792d42007 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/fma.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'fma' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn fma(e1: T ,e2: T ,e3: T ) -> T Returns e1 * e2 + e3. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns e1 * e2 + e3. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -30,8 +30,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('fma'), - [TypeAbstractFloat, TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -45,7 +45,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('fma'), [TypeF32, TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('fma'), [Type.f32, Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -59,5 +59,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('fma'), [TypeF16, TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('fma'), [Type.f16, Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts index df9e1845273e..d840122b3978 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/fract.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'fract' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn fract(e: T ) -> T Returns the fractional part of e, computed as e - floor(e). @@ -10,7 +10,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -34,7 +34,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('fract'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('fract'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -48,5 +48,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('fract'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('fract'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/frexp.cache.ts b/src/webgpu/shader/execution/expression/call/builtin/frexp.cache.ts index 7c107eb729a7..05f8de7f8936 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/frexp.cache.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/frexp.cache.ts @@ -1,5 +1,5 @@ import { skipUndefined } from '../../../../../util/compare.js'; -import { Scalar, Vector, i32, toVector } from '../../../../../util/conversion.js'; +import { ScalarValue, VectorValue, i32, toVector } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; import { frexp } from '../../../../../util/math.js'; import { Case } from '../../case.js'; @@ -8,8 +8,8 @@ import { makeCaseCache } from '../../case_cache.js'; /* @returns a fract Case for a given scalar or vector input */ function makeCaseFract(v: number | readonly number[], trait: 'f32' | 'f16'): Case { const fp = FP[trait]; - let toInput: (n: readonly number[]) => Scalar | Vector; - let toOutput: (n: readonly number[]) => Scalar | Vector; + let toInput: (n: readonly number[]) => ScalarValue | VectorValue; + let toOutput: (n: readonly number[]) => ScalarValue | VectorValue; if (v instanceof Array) { // Input is vector toInput = (n: readonly number[]) => toVector(n, fp.scalarBuilder); @@ -36,8 +36,8 @@ function makeCaseFract(v: number | readonly number[], trait: 'f32' | 'f16'): Cas /* @returns an exp Case for a given scalar or vector input */ function makeCaseExp(v: number | readonly number[], trait: 'f32' | 'f16'): Case { const fp = FP[trait]; - let toInput: (n: readonly number[]) => Scalar | Vector; - let toOutput: (n: readonly number[]) => Scalar | Vector; + let toInput: (n: readonly number[]) => ScalarValue | VectorValue; + let toOutput: (n: readonly number[]) => ScalarValue | VectorValue; if (v instanceof Array) { // Input is vector toInput = (n: readonly number[]) => toVector(n, fp.scalarBuilder); diff --git a/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts index 663e345f499a..ee506decd9d0 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/frexp.spec.ts @@ -15,7 +15,7 @@ The magnitude of the significand is in the range of [0.5, 1.0) or 0. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeI32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, basicExpressionBuilder, run } from '../../expression.js'; import { d } from './frexp.cache.js'; @@ -46,7 +46,7 @@ struct __frexp_result_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_fract'); - await run(t, fractBuilder(), [TypeF32], TypeF32, t.params, cases); + await run(t, fractBuilder(), [Type.f32], Type.f32, t.params, cases); }); g.test('f32_exp') @@ -64,7 +64,7 @@ struct __frexp_result_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_exp'); - await run(t, expBuilder(), [TypeF32], TypeI32, t.params, cases); + await run(t, expBuilder(), [Type.f32], Type.i32, t.params, cases); }); g.test('f32_vec2_fract') @@ -82,7 +82,7 @@ struct __frexp_result_vec2_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec2_fract'); - await run(t, fractBuilder(), [TypeVec(2, TypeF32)], TypeVec(2, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec2f], Type.vec2f, t.params, cases); }); g.test('f32_vec2_exp') @@ -100,7 +100,7 @@ struct __frexp_result_vec2_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec2_exp'); - await run(t, expBuilder(), [TypeVec(2, TypeF32)], TypeVec(2, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec2f], Type.vec2i, t.params, cases); }); g.test('f32_vec3_fract') @@ -118,7 +118,7 @@ struct __frexp_result_vec3_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec3_fract'); - await run(t, fractBuilder(), [TypeVec(3, TypeF32)], TypeVec(3, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f32_vec3_exp') @@ -136,7 +136,7 @@ struct __frexp_result_vec3_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec3_exp'); - await run(t, expBuilder(), [TypeVec(3, TypeF32)], TypeVec(3, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec3f], Type.vec3i, t.params, cases); }); g.test('f32_vec4_fract') @@ -154,7 +154,7 @@ struct __frexp_result_vec4_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec4_fract'); - await run(t, fractBuilder(), [TypeVec(4, TypeF32)], TypeVec(4, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec4f], Type.vec4f, t.params, cases); }); g.test('f32_vec4_exp') @@ -172,7 +172,7 @@ struct __frexp_result_vec4_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec4_exp'); - await run(t, expBuilder(), [TypeVec(4, TypeF32)], TypeVec(4, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec4f], Type.vec4i, t.params, cases); }); g.test('f16_fract') @@ -193,7 +193,7 @@ struct __frexp_result_f16 { }) .fn(async t => { const cases = await d.get('f16_fract'); - await run(t, fractBuilder(), [TypeF16], TypeF16, t.params, cases); + await run(t, fractBuilder(), [Type.f16], Type.f16, t.params, cases); }); g.test('f16_exp') @@ -214,7 +214,7 @@ struct __frexp_result_f16 { }) .fn(async t => { const cases = await d.get('f16_exp'); - await run(t, expBuilder(), [TypeF16], TypeI32, t.params, cases); + await run(t, expBuilder(), [Type.f16], Type.i32, t.params, cases); }); g.test('f16_vec2_fract') @@ -235,7 +235,7 @@ struct __frexp_result_vec2_f16 { }) .fn(async t => { const cases = await d.get('f16_vec2_fract'); - await run(t, fractBuilder(), [TypeVec(2, TypeF16)], TypeVec(2, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec2h], Type.vec2h, t.params, cases); }); g.test('f16_vec2_exp') @@ -256,7 +256,7 @@ struct __frexp_result_vec2_f16 { }) .fn(async t => { const cases = await d.get('f16_vec2_exp'); - await run(t, expBuilder(), [TypeVec(2, TypeF16)], TypeVec(2, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec2h], Type.vec2i, t.params, cases); }); g.test('f16_vec3_fract') @@ -277,7 +277,7 @@ struct __frexp_result_vec3_f16 { }) .fn(async t => { const cases = await d.get('f16_vec3_fract'); - await run(t, fractBuilder(), [TypeVec(3, TypeF16)], TypeVec(3, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec3h], Type.vec3h, t.params, cases); }); g.test('f16_vec3_exp') @@ -298,7 +298,7 @@ struct __frexp_result_vec3_f16 { }) .fn(async t => { const cases = await d.get('f16_vec3_exp'); - await run(t, expBuilder(), [TypeVec(3, TypeF16)], TypeVec(3, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec3h], Type.vec3i, t.params, cases); }); g.test('f16_vec4_fract') @@ -319,7 +319,7 @@ struct __frexp_result_vec4_f16 { }) .fn(async t => { const cases = await d.get('f16_vec4_fract'); - await run(t, fractBuilder(), [TypeVec(4, TypeF16)], TypeVec(4, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec4h], Type.vec4h, t.params, cases); }); g.test('f16_vec4_exp') @@ -340,5 +340,5 @@ struct __frexp_result_vec4_f16 { }) .fn(async t => { const cases = await d.get('f16_vec4_exp'); - await run(t, expBuilder(), [TypeVec(4, TypeF16)], TypeVec(4, TypeI32), t.params, cases); + await run(t, expBuilder(), [Type.vec4h], Type.vec4i, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/insertBits.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/insertBits.spec.ts index 1068e76252c2..b3eb65781d59 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/insertBits.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/insertBits.spec.ts @@ -18,17 +18,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - i32Bits, - TypeI32, - u32, - TypeU32, - u32Bits, - vec2, - vec3, - vec4, - TypeVec, -} from '../../../../../util/conversion.js'; +import { i32Bits, Type, u32, u32Bits, vec2, vec3, vec4 } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -46,8 +36,8 @@ g.test('integer') ) .fn(async t => { const cfg: Config = t.params; - const scalarType = t.params.signed ? TypeI32 : TypeU32; - const T = t.params.width === 1 ? scalarType : TypeVec(t.params.width, scalarType); + const scalarType = t.params.signed ? Type.i32 : Type.u32; + const T = t.params.width === 1 ? scalarType : Type.vec(t.params.width, scalarType); const V = (x: number, y?: number, z?: number, w?: number) => { y = y === undefined ? x : y; @@ -382,5 +372,5 @@ g.test('integer') ); } - await run(t, builtin('insertBits'), [T, T, TypeU32, TypeU32], T, cfg, cases); + await run(t, builtin('insertBits'), [T, T, Type.u32, Type.u32], T, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/inversesqrt.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/inversesqrt.spec.ts index fb5248ec8ad6..c27c56d4b5dd 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/inversesqrt.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/inversesqrt.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'inverseSqrt' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn inverseSqrt(e: T ) -> T Returns the reciprocal of sqrt(e). Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the reciprocal of sqrt(e). Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('inverseSqrt'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('inverseSqrt'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('inverseSqrt'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('inverseSqrt'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts index e2eba8232d43..b06a3ef55086 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/ldexp.spec.ts @@ -1,10 +1,10 @@ export const description = ` Execution tests for the 'ldexp' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN -K is AbstractInt, i32 +K is Type.abstractInt, i32 I is K or vecN, where I is a scalar if T is a scalar, or a vector when T is a vector @@ -14,7 +14,7 @@ Returns e1 * 2^e2. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeI32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -41,7 +41,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('ldexp'), [TypeF32, TypeI32], TypeF32, t.params, cases); + await run(t, builtin('ldexp'), [Type.f32, Type.i32], Type.f32, t.params, cases); }); g.test('f16') @@ -55,5 +55,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('ldexp'), [TypeF16, TypeI32], TypeF16, t.params, cases); + await run(t, builtin('ldexp'), [Type.f16, Type.i32], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts index e91d5dcdafe5..690bc6152b37 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/length.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'length' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn length(e: T ) -> f32 Returns the length of e (e.g. abs(e) if T is a scalar, or sqrt(e[0]^2 + e[1]^2 + ...) if T is a vector). @@ -9,7 +9,7 @@ Returns the length of e (e.g. abs(e) if T is a scalar, or sqrt(e[0]^2 + e[1]^2 + import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -31,7 +31,7 @@ g.test('f32') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('length'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('length'), [Type.f32], Type.f32, t.params, cases); }); g.test('f32_vec2') @@ -42,7 +42,7 @@ g.test('f32_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_const' : 'f32_vec2_non_const' ); - await run(t, builtin('length'), [TypeVec(2, TypeF32)], TypeF32, t.params, cases); + await run(t, builtin('length'), [Type.vec2f], Type.f32, t.params, cases); }); g.test('f32_vec3') @@ -53,7 +53,7 @@ g.test('f32_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_const' : 'f32_vec3_non_const' ); - await run(t, builtin('length'), [TypeVec(3, TypeF32)], TypeF32, t.params, cases); + await run(t, builtin('length'), [Type.vec3f], Type.f32, t.params, cases); }); g.test('f32_vec4') @@ -64,7 +64,7 @@ g.test('f32_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_const' : 'f32_vec4_non_const' ); - await run(t, builtin('length'), [TypeVec(4, TypeF32)], TypeF32, t.params, cases); + await run(t, builtin('length'), [Type.vec4f], Type.f32, t.params, cases); }); g.test('f16') @@ -76,7 +76,7 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('length'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('length'), [Type.f16], Type.f16, t.params, cases); }); g.test('f16_vec2') @@ -90,7 +90,7 @@ g.test('f16_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_const' : 'f16_vec2_non_const' ); - await run(t, builtin('length'), [TypeVec(2, TypeF16)], TypeF16, t.params, cases); + await run(t, builtin('length'), [Type.vec2h], Type.f16, t.params, cases); }); g.test('f16_vec3') @@ -104,7 +104,7 @@ g.test('f16_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_const' : 'f16_vec3_non_const' ); - await run(t, builtin('length'), [TypeVec(3, TypeF16)], TypeF16, t.params, cases); + await run(t, builtin('length'), [Type.vec3h], Type.f16, t.params, cases); }); g.test('f16_vec4') @@ -118,5 +118,5 @@ g.test('f16_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_const' : 'f16_vec4_non_const' ); - await run(t, builtin('length'), [TypeVec(4, TypeF16)], TypeF16, t.params, cases); + await run(t, builtin('length'), [Type.vec4h], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts index 387705320ff9..1d9814679002 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/log.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'log' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn log(e: T ) -> T Returns the natural logarithm of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the natural logarithm of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -39,7 +39,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('log'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('log'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -53,5 +53,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('log'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('log'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts index 86a38a60246a..497c66676cc3 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/log2.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'log2' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn log2(e: T ) -> T Returns the base-2 logarithm of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the base-2 logarithm of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -39,7 +39,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('log2'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('log2'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -53,5 +53,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('log2'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('log2'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts index 63e3fda3f2b6..ee7cb0d674f5 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/max.spec.ts @@ -1,12 +1,12 @@ export const description = ` Execution tests for the 'max' builtin function -S is AbstractInt, i32, or u32 +S is abstract-int, i32, or u32 T is S or vecN @const fn max(e1: T ,e2: T) -> T Returns e2 if e1 is less than e2, and e1 otherwise. Component-wise when T is a vector. -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is vecN @const fn max(e1: T ,e2: T) -> T Returns e2 if e1 is less than e2, and e1 otherwise. @@ -18,17 +18,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - TypeAbstractFloat, - TypeF16, - TypeF32, - TypeI32, - TypeU32, - i32, - u32, - abstractInt, - TypeAbstractInt, -} from '../../../../../util/conversion.js'; +import { Type, i32, u32, abstractInt } from '../../../../../util/conversion.js'; import { maxBigInt } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -66,8 +56,8 @@ g.test('abstract_int') await run( t, abstractIntBuiltin('max'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -87,7 +77,7 @@ g.test('u32') const test_values: number[] = [0, 1, 2, 0x70000000, 0x80000000, 0xffffffff]; const cases = generateTestCases(test_values, makeCase); - await run(t, builtin('max'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, builtin('max'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('i32') @@ -104,7 +94,7 @@ g.test('i32') const test_values: number[] = [-0x70000000, -2, -1, 0, 1, 2, 0x70000000]; const cases = generateTestCases(test_values, makeCase); - await run(t, builtin('max'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, builtin('max'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('abstract_float') @@ -120,8 +110,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('max'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -135,7 +125,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('max'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('max'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -149,5 +139,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('max'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('max'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts index 30f411196047..ac636413997d 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/min.spec.ts @@ -1,12 +1,12 @@ export const description = ` Execution tests for the 'min' builtin function -S is AbstractInt, i32, or u32 +S is abstract-int, i32, or u32 T is S or vecN @const fn min(e1: T ,e2: T) -> T Returns e1 if e1 is less than e2, and e2 otherwise. Component-wise when T is a vector. -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn min(e1: T ,e2: T) -> T Returns e2 if e2 is less than e1, and e1 otherwise. @@ -17,17 +17,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - TypeAbstractFloat, - TypeF16, - TypeF32, - TypeI32, - TypeU32, - i32, - u32, - abstractInt, - TypeAbstractInt, -} from '../../../../../util/conversion.js'; +import { Type, i32, u32, abstractInt } from '../../../../../util/conversion.js'; import { minBigInt } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; @@ -65,8 +55,8 @@ g.test('abstract_int') await run( t, abstractIntBuiltin('min'), - [TypeAbstractInt, TypeAbstractInt], - TypeAbstractInt, + [Type.abstractInt, Type.abstractInt], + Type.abstractInt, t.params, cases ); @@ -86,7 +76,7 @@ g.test('u32') const test_values: number[] = [0, 1, 2, 0x70000000, 0x80000000, 0xffffffff]; const cases = generateTestCases(test_values, makeCase); - await run(t, builtin('min'), [TypeU32, TypeU32], TypeU32, t.params, cases); + await run(t, builtin('min'), [Type.u32, Type.u32], Type.u32, t.params, cases); }); g.test('i32') @@ -103,7 +93,7 @@ g.test('i32') const test_values: number[] = [-0x70000000, -2, -1, 0, 1, 2, 0x70000000]; const cases = generateTestCases(test_values, makeCase); - await run(t, builtin('min'), [TypeI32, TypeI32], TypeI32, t.params, cases); + await run(t, builtin('min'), [Type.i32, Type.i32], Type.i32, t.params, cases); }); g.test('abstract_float') @@ -119,8 +109,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('min'), - [TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -134,7 +124,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('min'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('min'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -148,5 +138,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('min'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('min'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts index d502c639620b..0005ab5c0eeb 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/mix.spec.ts @@ -1,12 +1,12 @@ export const description = ` Execution tests for the 'mix' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn mix(e1: T, e2: T, e3: T) -> T Returns the linear blend of e1 and e2 (e.g. e1*(1-e3)+e2*e3). Component-wise when T is a vector. -T is AbstractFloat, f32, or f16 +T is abstract-float, f32, or f16 T2 is vecN @const fn mix(e1: T2, e2: T2, e3: T) -> T2 Returns the component-wise linear blend of e1 and e2, using scalar blending factor e3 for each component. @@ -16,7 +16,7 @@ Same as mix(e1,e2,T2(e3)). import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -37,8 +37,8 @@ g.test('abstract_float_matching') await run( t, abstractFloatBuiltin('mix'), - [TypeAbstractFloat, TypeAbstractFloat, TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat, Type.abstractFloat, Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -53,8 +53,8 @@ g.test('abstract_float_nonmatching_vec2') await run( t, abstractFloatBuiltin('mix'), - [TypeVec(2, TypeAbstractFloat), TypeVec(2, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(2, TypeAbstractFloat), + [Type.vec(2, Type.abstractFloat), Type.vec(2, Type.abstractFloat), Type.abstractFloat], + Type.vec(2, Type.abstractFloat), t.params, cases ); @@ -69,8 +69,8 @@ g.test('abstract_float_nonmatching_vec3') await run( t, abstractFloatBuiltin('mix'), - [TypeVec(3, TypeAbstractFloat), TypeVec(3, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(3, TypeAbstractFloat), + [Type.vec(3, Type.abstractFloat), Type.vec(3, Type.abstractFloat), Type.abstractFloat], + Type.vec(3, Type.abstractFloat), t.params, cases ); @@ -85,8 +85,8 @@ g.test('abstract_float_nonmatching_vec4') await run( t, abstractFloatBuiltin('mix'), - [TypeVec(4, TypeAbstractFloat), TypeVec(4, TypeAbstractFloat), TypeAbstractFloat], - TypeVec(4, TypeAbstractFloat), + [Type.vec(4, Type.abstractFloat), Type.vec(4, Type.abstractFloat), Type.abstractFloat], + Type.vec(4, Type.abstractFloat), t.params, cases ); @@ -100,7 +100,7 @@ g.test('f32_matching') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('mix'), [TypeF32, TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('mix'), [Type.f32, Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f32_nonmatching_vec2') @@ -111,14 +111,7 @@ g.test('f32_nonmatching_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_scalar_const' : 'f32_vec2_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32), TypeF32], - TypeVec(2, TypeF32), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec2f, Type.vec2f, Type.f32], Type.vec2f, t.params, cases); }); g.test('f32_nonmatching_vec3') @@ -129,14 +122,7 @@ g.test('f32_nonmatching_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_scalar_const' : 'f32_vec3_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32), TypeF32], - TypeVec(3, TypeF32), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec3f, Type.vec3f, Type.f32], Type.vec3f, t.params, cases); }); g.test('f32_nonmatching_vec4') @@ -147,14 +133,7 @@ g.test('f32_nonmatching_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_scalar_const' : 'f32_vec4_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32), TypeF32], - TypeVec(4, TypeF32), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec4f, Type.vec4f, Type.f32], Type.vec4f, t.params, cases); }); g.test('f16_matching') @@ -168,7 +147,7 @@ g.test('f16_matching') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('mix'), [TypeF16, TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('mix'), [Type.f16, Type.f16, Type.f16], Type.f16, t.params, cases); }); g.test('f16_nonmatching_vec2') @@ -182,14 +161,7 @@ g.test('f16_nonmatching_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_scalar_const' : 'f16_vec2_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16), TypeF16], - TypeVec(2, TypeF16), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec2h, Type.vec2h, Type.f16], Type.vec2h, t.params, cases); }); g.test('f16_nonmatching_vec3') @@ -203,14 +175,7 @@ g.test('f16_nonmatching_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_scalar_const' : 'f16_vec3_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16), TypeF16], - TypeVec(3, TypeF16), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec3h, Type.vec3h, Type.f16], Type.vec3h, t.params, cases); }); g.test('f16_nonmatching_vec4') @@ -224,12 +189,5 @@ g.test('f16_nonmatching_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_scalar_const' : 'f16_vec4_scalar_non_const' ); - await run( - t, - builtin('mix'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16), TypeF16], - TypeVec(4, TypeF16), - t.params, - cases - ); + await run(t, builtin('mix'), [Type.vec4h, Type.vec4h, Type.f16], Type.vec4h, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts index 3e12d4f8696d..6c988008f825 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/modf.spec.ts @@ -1,13 +1,13 @@ export const description = ` Execution tests for the 'modf' builtin function -T is f32 or f16 or AbstractFloat +T is f32 or f16 or Type.abstractFloat @const fn modf(e:T) -> result_struct Splits |e| into fractional and whole number parts. The whole part is (|e| % 1.0), and the fractional part is |e| minus the whole part. Returns the result_struct for the given type. -S is f32 or f16 or AbstractFloat +S is f32 or f16 or Type.abstractFloat T is vecN @const fn modf(e:T) -> result_struct Splits the components of |e| into fractional and whole number parts. @@ -18,7 +18,7 @@ Returns the result_struct for the given type. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { abstractFloatShaderBuilder, allInputSources, @@ -67,7 +67,7 @@ struct __modf_result_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_fract'); - await run(t, fractBuilder(), [TypeF32], TypeF32, t.params, cases); + await run(t, fractBuilder(), [Type.f32], Type.f32, t.params, cases); }); g.test('f32_whole') @@ -85,7 +85,7 @@ struct __modf_result_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_whole'); - await run(t, wholeBuilder(), [TypeF32], TypeF32, t.params, cases); + await run(t, wholeBuilder(), [Type.f32], Type.f32, t.params, cases); }); g.test('f32_vec2_fract') @@ -103,7 +103,7 @@ struct __modf_result_vec2_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec2_fract'); - await run(t, fractBuilder(), [TypeVec(2, TypeF32)], TypeVec(2, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec2f], Type.vec2f, t.params, cases); }); g.test('f32_vec2_whole') @@ -121,7 +121,7 @@ struct __modf_result_vec2_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec2_whole'); - await run(t, wholeBuilder(), [TypeVec(2, TypeF32)], TypeVec(2, TypeF32), t.params, cases); + await run(t, wholeBuilder(), [Type.vec2f], Type.vec2f, t.params, cases); }); g.test('f32_vec3_fract') @@ -139,7 +139,7 @@ struct __modf_result_vec3_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec3_fract'); - await run(t, fractBuilder(), [TypeVec(3, TypeF32)], TypeVec(3, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f32_vec3_whole') @@ -157,7 +157,7 @@ struct __modf_result_vec3_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec3_whole'); - await run(t, wholeBuilder(), [TypeVec(3, TypeF32)], TypeVec(3, TypeF32), t.params, cases); + await run(t, wholeBuilder(), [Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f32_vec4_fract') @@ -175,7 +175,7 @@ struct __modf_result_vec4_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec4_fract'); - await run(t, fractBuilder(), [TypeVec(4, TypeF32)], TypeVec(4, TypeF32), t.params, cases); + await run(t, fractBuilder(), [Type.vec4f], Type.vec4f, t.params, cases); }); g.test('f32_vec4_whole') @@ -193,7 +193,7 @@ struct __modf_result_vec4_f32 { .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get('f32_vec4_whole'); - await run(t, wholeBuilder(), [TypeVec(4, TypeF32)], TypeVec(4, TypeF32), t.params, cases); + await run(t, wholeBuilder(), [Type.vec4f], Type.vec4f, t.params, cases); }); g.test('f16_fract') @@ -214,7 +214,7 @@ struct __modf_result_f16 { }) .fn(async t => { const cases = await d.get('f16_fract'); - await run(t, fractBuilder(), [TypeF16], TypeF16, t.params, cases); + await run(t, fractBuilder(), [Type.f16], Type.f16, t.params, cases); }); g.test('f16_whole') @@ -235,7 +235,7 @@ struct __modf_result_f16 { }) .fn(async t => { const cases = await d.get('f16_whole'); - await run(t, wholeBuilder(), [TypeF16], TypeF16, t.params, cases); + await run(t, wholeBuilder(), [Type.f16], Type.f16, t.params, cases); }); g.test('f16_vec2_fract') @@ -256,7 +256,7 @@ struct __modf_result_vec2_f16 { }) .fn(async t => { const cases = await d.get('f16_vec2_fract'); - await run(t, fractBuilder(), [TypeVec(2, TypeF16)], TypeVec(2, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec2h], Type.vec2h, t.params, cases); }); g.test('f16_vec2_whole') @@ -277,7 +277,7 @@ struct __modf_result_vec2_f16 { }) .fn(async t => { const cases = await d.get('f16_vec2_whole'); - await run(t, wholeBuilder(), [TypeVec(2, TypeF16)], TypeVec(2, TypeF16), t.params, cases); + await run(t, wholeBuilder(), [Type.vec2h], Type.vec2h, t.params, cases); }); g.test('f16_vec3_fract') @@ -298,7 +298,7 @@ struct __modf_result_vec3_f16 { }) .fn(async t => { const cases = await d.get('f16_vec3_fract'); - await run(t, fractBuilder(), [TypeVec(3, TypeF16)], TypeVec(3, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec3h], Type.vec3h, t.params, cases); }); g.test('f16_vec3_whole') @@ -319,7 +319,7 @@ struct __modf_result_vec3_f16 { }) .fn(async t => { const cases = await d.get('f16_vec3_whole'); - await run(t, wholeBuilder(), [TypeVec(3, TypeF16)], TypeVec(3, TypeF16), t.params, cases); + await run(t, wholeBuilder(), [Type.vec3h], Type.vec3h, t.params, cases); }); g.test('f16_vec4_fract') @@ -340,7 +340,7 @@ struct __modf_result_vec4_f16 { }) .fn(async t => { const cases = await d.get('f16_vec4_fract'); - await run(t, fractBuilder(), [TypeVec(4, TypeF16)], TypeVec(4, TypeF16), t.params, cases); + await run(t, fractBuilder(), [Type.vec4h], Type.vec4h, t.params, cases); }); g.test('f16_vec4_whole') @@ -361,43 +361,43 @@ struct __modf_result_vec4_f16 { }) .fn(async t => { const cases = await d.get('f16_vec4_whole'); - await run(t, wholeBuilder(), [TypeVec(4, TypeF16)], TypeVec(4, TypeF16), t.params, cases); + await run(t, wholeBuilder(), [Type.vec4h], Type.vec4h, t.params, cases); }); g.test('abstract_fract') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc( ` -T is AbstractFloat +T is abstract-float struct __modf_result_abstract { - fract : AbstractFloat, // fractional part - whole : AbstractFloat // whole part + fract : Type.abstractFloat, // fractional part + whole : Type.abstractFloat // whole part } ` ) .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('abstract_fract'); - await run(t, abstractFractBuilder(), [TypeAbstractFloat], TypeAbstractFloat, t.params, cases); + await run(t, abstractFractBuilder(), [Type.abstractFloat], Type.abstractFloat, t.params, cases); }); g.test('abstract_whole') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc( ` -T is AbstractFloat +T is abstract-float struct __modf_result_abstract { - fract : AbstractFloat, // fractional part - whole : AbstractFloat // whole part + fract : Type.abstractFloat, // fractional part + whole : Type.abstractFloat // whole part } ` ) .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('abstract_whole'); - await run(t, abstractWholeBuilder(), [TypeAbstractFloat], TypeAbstractFloat, t.params, cases); + await run(t, abstractWholeBuilder(), [Type.abstractFloat], Type.abstractFloat, t.params, cases); }); g.test('abstract_vec2_fract') @@ -418,8 +418,8 @@ struct __modf_result_vec2_abstract { await run( t, abstractFractBuilder(), - [TypeVec(2, TypeAbstractFloat)], - TypeVec(2, TypeAbstractFloat), + [Type.vec(2, Type.abstractFloat)], + Type.vec(2, Type.abstractFloat), t.params, cases ); @@ -443,8 +443,8 @@ struct __modf_result_vec2_abstract { await run( t, abstractWholeBuilder(), - [TypeVec(2, TypeAbstractFloat)], - TypeVec(2, TypeAbstractFloat), + [Type.vec(2, Type.abstractFloat)], + Type.vec(2, Type.abstractFloat), t.params, cases ); @@ -468,8 +468,8 @@ struct __modf_result_vec3_abstract { await run( t, abstractFractBuilder(), - [TypeVec(3, TypeAbstractFloat)], - TypeVec(3, TypeAbstractFloat), + [Type.vec(3, Type.abstractFloat)], + Type.vec(3, Type.abstractFloat), t.params, cases ); @@ -493,8 +493,8 @@ struct __modf_result_vec3_abstract { await run( t, abstractWholeBuilder(), - [TypeVec(3, TypeAbstractFloat)], - TypeVec(3, TypeAbstractFloat), + [Type.vec(3, Type.abstractFloat)], + Type.vec(3, Type.abstractFloat), t.params, cases ); @@ -518,8 +518,8 @@ struct __modf_result_vec4_abstract { await run( t, abstractFractBuilder(), - [TypeVec(4, TypeAbstractFloat)], - TypeVec(4, TypeAbstractFloat), + [Type.vec(4, Type.abstractFloat)], + Type.vec(4, Type.abstractFloat), t.params, cases ); @@ -543,8 +543,8 @@ struct __modf_result_vec4_abstract { await run( t, abstractWholeBuilder(), - [TypeVec(4, TypeAbstractFloat)], - TypeVec(4, TypeAbstractFloat), + [Type.vec(4, Type.abstractFloat)], + Type.vec(4, Type.abstractFloat), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/call/builtin/normalize.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/normalize.spec.ts index 4820f5884d69..7aca252464da 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/normalize.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/normalize.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'normalize' builtin function -T is AbstractFloat, f32, or f16 +T is abstract-float, f32, or f16 @const fn normalize(e: vecN ) -> vecN Returns a unit vector in the same direction as e. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -32,7 +32,7 @@ g.test('f32_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_const' : 'f32_vec2_non_const' ); - await run(t, builtin('normalize'), [TypeVec(2, TypeF32)], TypeVec(2, TypeF32), t.params, cases); + await run(t, builtin('normalize'), [Type.vec2f], Type.vec2f, t.params, cases); }); g.test('f32_vec3') @@ -43,7 +43,7 @@ g.test('f32_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_const' : 'f32_vec3_non_const' ); - await run(t, builtin('normalize'), [TypeVec(3, TypeF32)], TypeVec(3, TypeF32), t.params, cases); + await run(t, builtin('normalize'), [Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f32_vec4') @@ -54,7 +54,7 @@ g.test('f32_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_const' : 'f32_vec4_non_const' ); - await run(t, builtin('normalize'), [TypeVec(4, TypeF32)], TypeVec(4, TypeF32), t.params, cases); + await run(t, builtin('normalize'), [Type.vec4f], Type.vec4f, t.params, cases); }); g.test('f16_vec2') @@ -68,7 +68,7 @@ g.test('f16_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_const' : 'f16_vec2_non_const' ); - await run(t, builtin('normalize'), [TypeVec(2, TypeF16)], TypeVec(2, TypeF16), t.params, cases); + await run(t, builtin('normalize'), [Type.vec2h], Type.vec2h, t.params, cases); }); g.test('f16_vec3') @@ -82,7 +82,7 @@ g.test('f16_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_const' : 'f16_vec3_non_const' ); - await run(t, builtin('normalize'), [TypeVec(3, TypeF16)], TypeVec(3, TypeF16), t.params, cases); + await run(t, builtin('normalize'), [Type.vec3h], Type.vec3h, t.params, cases); }); g.test('f16_vec4') @@ -96,5 +96,5 @@ g.test('f16_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_const' : 'f16_vec4_non_const' ); - await run(t, builtin('normalize'), [TypeVec(4, TypeF16)], TypeVec(4, TypeF16), t.params, cases); + await run(t, builtin('normalize'), [Type.vec4h], Type.vec4h, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts index efa4041259eb..5ba69934279f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack2x16float.spec.ts @@ -6,7 +6,7 @@ which is then placed in bits 16 × i through 16 × i + 15 of the result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -24,5 +24,5 @@ g.test('pack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('pack2x16float'), [TypeVec(2, TypeF32)], TypeU32, t.params, cases); + await run(t, builtin('pack2x16float'), [Type.vec2f], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack2x16snorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack2x16snorm.spec.ts index 6479fe7ce070..1bcca2f73fe2 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack2x16snorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack2x16snorm.spec.ts @@ -8,15 +8,7 @@ bits 16 × i through 16 × i + 15 of the result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { kValue } from '../../../../../util/constants.js'; -import { - f32, - pack2x16snorm, - TypeF32, - TypeU32, - TypeVec, - u32, - vec2, -} from '../../../../../util/conversion.js'; +import { f32, pack2x16snorm, u32, vec2, Type } from '../../../../../util/conversion.js'; import { quantizeToF32, vectorF32Range } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, run } from '../../expression.js'; @@ -52,5 +44,5 @@ g.test('pack') ]; }); - await run(t, builtin('pack2x16snorm'), [TypeVec(2, TypeF32)], TypeU32, t.params, cases); + await run(t, builtin('pack2x16snorm'), [Type.vec2f], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack2x16unorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack2x16unorm.spec.ts index 303c555c1daf..334d1064824c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack2x16unorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack2x16unorm.spec.ts @@ -8,15 +8,7 @@ bits 16 × i through 16 × i + 15 of the result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { kValue } from '../../../../../util/constants.js'; -import { - f32, - pack2x16unorm, - TypeF32, - TypeU32, - TypeVec, - u32, - vec2, -} from '../../../../../util/conversion.js'; +import { f32, pack2x16unorm, u32, vec2, Type } from '../../../../../util/conversion.js'; import { quantizeToF32, vectorF32Range } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, run } from '../../expression.js'; @@ -52,5 +44,5 @@ g.test('pack') ]; }); - await run(t, builtin('pack2x16unorm'), [TypeVec(2, TypeF32)], TypeU32, t.params, cases); + await run(t, builtin('pack2x16unorm'), [Type.vec2f], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4x8snorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4x8snorm.spec.ts index b1c2607c940f..fbe362ea45e8 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4x8snorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4x8snorm.spec.ts @@ -8,16 +8,7 @@ bits 8 × i through 8 × i + 7 of the result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { kValue } from '../../../../../util/constants.js'; -import { - f32, - pack4x8snorm, - Scalar, - TypeF32, - TypeU32, - TypeVec, - u32, - vec4, -} from '../../../../../util/conversion.js'; +import { f32, pack4x8snorm, ScalarValue, u32, vec4, Type } from '../../../../../util/conversion.js'; import { quantizeToF32, vectorF32Range } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, run } from '../../expression.js'; @@ -36,7 +27,12 @@ g.test('pack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const makeCase = (vals: [number, number, number, number]): Case => { - const vals_f32 = new Array(4) as [Scalar, Scalar, Scalar, Scalar]; + const vals_f32 = new Array(4) as [ + ScalarValue, + ScalarValue, + ScalarValue, + ScalarValue, + ]; for (const idx in vals) { vals[idx] = quantizeToF32(vals[idx]); vals_f32[idx] = f32(vals[idx]); @@ -57,5 +53,5 @@ g.test('pack') ]; }); - await run(t, builtin('pack4x8snorm'), [TypeVec(4, TypeF32)], TypeU32, t.params, cases); + await run(t, builtin('pack4x8snorm'), [Type.vec4f], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4x8unorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4x8unorm.spec.ts index fa67e8f4ae3d..c7d62e722b24 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4x8unorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4x8unorm.spec.ts @@ -8,16 +8,7 @@ bits 8 × i through 8 × i + 7 of the result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; import { kValue } from '../../../../../util/constants.js'; -import { - f32, - pack4x8unorm, - Scalar, - TypeF32, - TypeU32, - TypeVec, - u32, - vec4, -} from '../../../../../util/conversion.js'; +import { f32, pack4x8unorm, ScalarValue, u32, vec4, Type } from '../../../../../util/conversion.js'; import { quantizeToF32, vectorF32Range } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, run } from '../../expression.js'; @@ -36,7 +27,12 @@ g.test('pack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const makeCase = (vals: [number, number, number, number]): Case => { - const vals_f32 = new Array(4) as [Scalar, Scalar, Scalar, Scalar]; + const vals_f32 = new Array(4) as [ + ScalarValue, + ScalarValue, + ScalarValue, + ScalarValue, + ]; for (const idx in vals) { vals[idx] = quantizeToF32(vals[idx]); vals_f32[idx] = f32(vals[idx]); @@ -57,5 +53,5 @@ g.test('pack') ]; }); - await run(t, builtin('pack4x8unorm'), [TypeVec(4, TypeF32)], TypeU32, t.params, cases); + await run(t, builtin('pack4x8unorm'), [Type.vec4f], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4xI8.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4xI8.spec.ts index 8caae09eba7c..94aa67f0ae85 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4xI8.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4xI8.spec.ts @@ -8,7 +8,7 @@ Component e[i] of the input is mapped to bits (8 * i) through (8 * (i + 7)) of t import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeI32, TypeU32, TypeVec, u32, toVector, i32 } from '../../../../../util/conversion.js'; +import { u32, toVector, i32, Type } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -65,5 +65,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('pack4xI8'), [TypeVec(4, TypeI32)], TypeU32, cfg, cases); + await run(t, builtin('pack4xI8'), [Type.vec4i], Type.u32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4xI8Clamp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4xI8Clamp.spec.ts index 0ab63d89beef..4968ed1e04de 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4xI8Clamp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4xI8Clamp.spec.ts @@ -9,7 +9,7 @@ result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeI32, TypeU32, TypeVec, u32, toVector, i32 } from '../../../../../util/conversion.js'; +import { u32, toVector, i32, Type } from '../../../../../util/conversion.js'; import { clamp } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -69,5 +69,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('pack4xI8Clamp'), [TypeVec(4, TypeI32)], TypeU32, cfg, cases); + await run(t, builtin('pack4xI8Clamp'), [Type.vec4i], Type.u32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4xU8.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4xU8.spec.ts index 0d4d2223f05d..9d08e88d4432 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4xU8.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4xU8.spec.ts @@ -8,7 +8,7 @@ Component e[i] of the input is mapped to bits (8 * i) through (8 * (i + 7)) of t import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, TypeVec, u32, toVector } from '../../../../../util/conversion.js'; +import { u32, toVector, Type } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -50,5 +50,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('pack4xU8'), [TypeVec(4, TypeU32)], TypeU32, cfg, cases); + await run(t, builtin('pack4xU8'), [Type.vec4u], Type.u32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pack4xU8Clamp.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pack4xU8Clamp.spec.ts index 0f70cb6f8c87..ffecf9b8779c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pack4xU8Clamp.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pack4xU8Clamp.spec.ts @@ -9,7 +9,7 @@ result. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, TypeVec, u32, toVector } from '../../../../../util/conversion.js'; +import { u32, toVector, Type } from '../../../../../util/conversion.js'; import { clamp } from '../../../../../util/math.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -53,5 +53,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('pack4xU8Clamp'), [TypeVec(4, TypeU32)], TypeU32, cfg, cases); + await run(t, builtin('pack4xU8Clamp'), [Type.vec4u], Type.u32, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts index deea077e7a31..476c591a358e 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/pow.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'pow' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn pow(e1: T ,e2: T ) -> T Returns e1 raised to the power e2. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns e1 raised to the power e2. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('pow'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('pow'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('pow'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('pow'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts index ee34ddd17479..0aa9669e93b3 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/quantizeToF16.spec.ts @@ -10,7 +10,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -26,5 +26,5 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('quantizeToF16'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('quantizeToF16'), [Type.f32], Type.f32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts index afc7da6d8cdb..a405807ec044 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/radians.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'radians' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn radians(e1: T ) -> T Converts degrees to radians, approximating e1 * π / 180. @@ -10,7 +10,7 @@ Component-wise when T is a vector import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -31,8 +31,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('radians'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -46,7 +46,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('radians'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('radians'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -60,5 +60,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('radians'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('radians'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/reflect.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/reflect.spec.ts index 0908bf04be5c..9c1a25f22a60 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/reflect.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/reflect.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'reflect' builtin function -T is vecN, vecN, or vecN +T is vecN, vecN, or vecN @const fn reflect(e1: T, e2: T ) -> T For the incident vector e1 and surface orientation e2, returns the reflection direction e1-2*dot(e2,e1)*e2. @@ -9,7 +9,7 @@ direction e1-2*dot(e2,e1)*e2. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -31,14 +31,7 @@ g.test('f32_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec2_const' : 'f32_vec2_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32)], - TypeVec(2, TypeF32), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec2f, Type.vec2f], Type.vec2f, t.params, cases); }); g.test('f32_vec3') @@ -49,14 +42,7 @@ g.test('f32_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec3_const' : 'f32_vec3_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32)], - TypeVec(3, TypeF32), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec3f, Type.vec3f], Type.vec3f, t.params, cases); }); g.test('f32_vec4') @@ -67,14 +53,7 @@ g.test('f32_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f32_vec4_const' : 'f32_vec4_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32)], - TypeVec(4, TypeF32), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec4f, Type.vec4f], Type.vec4f, t.params, cases); }); g.test('f16_vec2') @@ -88,14 +67,7 @@ g.test('f16_vec2') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec2_const' : 'f16_vec2_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16)], - TypeVec(2, TypeF16), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec2h, Type.vec2h], Type.vec2h, t.params, cases); }); g.test('f16_vec3') @@ -109,14 +81,7 @@ g.test('f16_vec3') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec3_const' : 'f16_vec3_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16)], - TypeVec(3, TypeF16), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec3h, Type.vec3h], Type.vec3h, t.params, cases); }); g.test('f16_vec4') @@ -130,12 +95,5 @@ g.test('f16_vec4') const cases = await d.get( t.params.inputSource === 'const' ? 'f16_vec4_const' : 'f16_vec4_non_const' ); - await run( - t, - builtin('reflect'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16)], - TypeVec(4, TypeF16), - t.params, - cases - ); + await run(t, builtin('reflect'), [Type.vec4h, Type.vec4h], Type.vec4h, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts index 67eb8ac94658..466c9be7d922 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/refract.spec.ts @@ -2,7 +2,7 @@ export const description = ` Execution tests for the 'refract' builtin function T is vecN -I is AbstractFloat, f32, or f16 +I is abstract-float, f32, or f16 @const fn refract(e1: T ,e2: T ,e3: I ) -> T For the incident vector e1 and surface normal e2, and the ratio of indices of refraction e3, let k = 1.0 -e3*e3* (1.0 - dot(e2,e1) * dot(e2,e1)). @@ -12,7 +12,7 @@ vector e3*e1- (e3* dot(e2,e1) + sqrt(k)) *e2. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -37,8 +37,8 @@ g.test('f32_vec2') await run( t, builtin('refract'), - [TypeVec(2, TypeF32), TypeVec(2, TypeF32), TypeF32], - TypeVec(2, TypeF32), + [Type.vec2f, Type.vec2f, Type.f32], + Type.vec2f, t.params, cases ); @@ -55,8 +55,8 @@ g.test('f32_vec3') await run( t, builtin('refract'), - [TypeVec(3, TypeF32), TypeVec(3, TypeF32), TypeF32], - TypeVec(3, TypeF32), + [Type.vec3f, Type.vec3f, Type.f32], + Type.vec3f, t.params, cases ); @@ -73,8 +73,8 @@ g.test('f32_vec4') await run( t, builtin('refract'), - [TypeVec(4, TypeF32), TypeVec(4, TypeF32), TypeF32], - TypeVec(4, TypeF32), + [Type.vec4f, Type.vec4f, Type.f32], + Type.vec4f, t.params, cases ); @@ -94,8 +94,8 @@ g.test('f16_vec2') await run( t, builtin('refract'), - [TypeVec(2, TypeF16), TypeVec(2, TypeF16), TypeF16], - TypeVec(2, TypeF16), + [Type.vec2h, Type.vec2h, Type.f16], + Type.vec2h, t.params, cases ); @@ -115,8 +115,8 @@ g.test('f16_vec3') await run( t, builtin('refract'), - [TypeVec(3, TypeF16), TypeVec(3, TypeF16), TypeF16], - TypeVec(3, TypeF16), + [Type.vec3h, Type.vec3h, Type.f16], + Type.vec3h, t.params, cases ); @@ -136,8 +136,8 @@ g.test('f16_vec4') await run( t, builtin('refract'), - [TypeVec(4, TypeF16), TypeVec(4, TypeF16), TypeF16], - TypeVec(4, TypeF16), + [Type.vec4h, Type.vec4h, Type.f16], + Type.vec4h, t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/call/builtin/reverseBits.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/reverseBits.spec.ts index 6acb35982216..e235e62a5284 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/reverseBits.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/reverseBits.spec.ts @@ -10,7 +10,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, u32Bits, TypeI32, i32Bits } from '../../../../../util/conversion.js'; +import { u32Bits, i32Bits, Type } from '../../../../../util/conversion.js'; import { allInputSources, Config, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -26,7 +26,7 @@ g.test('u32') .fn(async t => { const cfg: Config = t.params; // prettier-ignore - await run(t, builtin('reverseBits'), [TypeU32], TypeU32, cfg, [ + await run(t, builtin('reverseBits'), [Type.u32], Type.u32, cfg, [ // Zero { input: u32Bits(0b00000000000000000000000000000000), expected: u32Bits(0b00000000000000000000000000000000) }, @@ -142,7 +142,7 @@ g.test('i32') .fn(async t => { const cfg: Config = t.params; // prettier-ignore - await run(t, builtin('reverseBits'), [TypeI32], TypeI32, cfg, [ + await run(t, builtin('reverseBits'), [Type.i32], Type.i32, cfg, [ // Zero { input: i32Bits(0b00000000000000000000000000000000), expected: i32Bits(0b00000000000000000000000000000000) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts index 8d215b952d59..eeaf41b38185 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'round' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn round(e: T) -> T Result is the integer k nearest to e, as a floating point value. @@ -12,7 +12,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -33,8 +33,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('round'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -48,7 +48,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('round'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('round'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -62,5 +62,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('round'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('round'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts index 216ffb734578..79c61e4eec6c 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/saturate.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'saturate' builtin function -S is AbstractFloat, f32, or f16 +S is abstract-float, f32, or f16 T is S or vecN @const fn saturate(e: T) -> T Returns clamp(e, 0.0, 1.0). Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns clamp(e, 0.0, 1.0). Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -30,8 +30,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('saturate'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -44,7 +44,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('saturate'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('saturate'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -58,5 +58,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('saturate'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('saturate'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/select.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/select.spec.ts index 757783f77da0..63accbc2d466 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/select.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/select.spec.ts @@ -14,12 +14,6 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { GPUTest } from '../../../../../gpu_test.js'; import { VectorType, - TypeVec, - TypeBool, - TypeF32, - TypeF16, - TypeI32, - TypeU32, f32, f16, i32, @@ -31,12 +25,11 @@ import { vec3, vec4, abstractFloat, - TypeAbstractFloat, - TypeAbstractInt, abstractInt, - Scalar, + ScalarValue, + Type, } from '../../../../../util/conversion.js'; -import { CaseList } from '../../case.js'; +import { Case } from '../../case.js'; import { run, allInputSources } from '../../expression.js'; import { abstractFloatBuiltin, abstractIntBuiltin, builtin } from './builtin.js'; @@ -51,41 +44,41 @@ type scalarKind = 'b' | 'af' | 'f' | 'h' | 'ai' | 'i' | 'u'; const dataType = { b: { - type: TypeBool, + type: Type.bool, scalar_builder: makeBool, shader_builder: builtin('select'), }, af: { - type: TypeAbstractFloat, + type: Type.abstractFloat, scalar_builder: abstractFloat, shader_builder: abstractFloatBuiltin('select'), }, f: { - type: TypeF32, + type: Type.f32, scalar_builder: f32, shader_builder: builtin('select'), }, h: { - type: TypeF16, + type: Type.f16, scalar_builder: f16, shader_builder: builtin('select'), }, ai: { - type: TypeAbstractInt, + type: Type.abstractInt, // Only ints are used in the tests below, so the conversion to bigint will // be safe. If a non-int is passed in this will Error. - scalar_builder: (v: number): Scalar => { + scalar_builder: (v: number): ScalarValue => { return abstractInt(BigInt(v)); }, shader_builder: abstractIntBuiltin('select'), }, i: { - type: TypeI32, + type: Type.i32, scalar_builder: i32, shader_builder: builtin('select'), }, u: { - type: TypeU32, + type: Type.u32, scalar_builder: u32, shader_builder: builtin('select'), }, @@ -136,21 +129,21 @@ g.test('scalar') ], }, vec2: { - type: TypeVec(2, componentType), + type: Type.vec(2, componentType), cases: [ { input: [v2a, v2b, False], expected: v2a }, { input: [v2a, v2b, True], expected: v2b }, ], }, vec3: { - type: TypeVec(3, componentType), + type: Type.vec(3, componentType), cases: [ { input: [v3a, v3b, False], expected: v3a }, { input: [v3a, v3b, True], expected: v3b }, ], }, vec4: { - type: TypeVec(4, componentType), + type: Type.vec(4, componentType), cases: [ { input: [v4a, v4b, False], expected: v4a }, { input: [v4a, v4b, True], expected: v4b }, @@ -162,7 +155,7 @@ g.test('scalar') await run( t, dataType[t.params.component as scalarKind].shader_builder, - [overload.type, overload.type, TypeBool], + [overload.type, overload.type, Type.bool], overload.type, t.params, overload.cases @@ -198,15 +191,15 @@ g.test('vector') const T = True; const F = False; - let tests: { dataType: VectorType; boolType: VectorType; cases: CaseList }; + let tests: { dataType: VectorType; boolType: VectorType; cases: Case[] }; switch (t.params.overload) { case 'vec2': { const a = vec2(scalars[0], scalars[1]); const b = vec2(scalars[4], scalars[5]); tests = { - dataType: TypeVec(2, componentType), - boolType: TypeVec(2, TypeBool), + dataType: Type.vec(2, componentType), + boolType: Type.vec(2, Type.bool), cases: [ { input: [a, b, vec2(F, F)], expected: vec2(a.x, a.y) }, { input: [a, b, vec2(F, T)], expected: vec2(a.x, b.y) }, @@ -220,8 +213,8 @@ g.test('vector') const a = vec3(scalars[0], scalars[1], scalars[2]); const b = vec3(scalars[4], scalars[5], scalars[6]); tests = { - dataType: TypeVec(3, componentType), - boolType: TypeVec(3, TypeBool), + dataType: Type.vec(3, componentType), + boolType: Type.vec(3, Type.bool), cases: [ { input: [a, b, vec3(F, F, F)], expected: vec3(a.x, a.y, a.z) }, { input: [a, b, vec3(F, F, T)], expected: vec3(a.x, a.y, b.z) }, @@ -239,8 +232,8 @@ g.test('vector') const a = vec4(scalars[0], scalars[1], scalars[2], scalars[3]); const b = vec4(scalars[4], scalars[5], scalars[6], scalars[7]); tests = { - dataType: TypeVec(4, componentType), - boolType: TypeVec(4, TypeBool), + dataType: Type.vec(4, componentType), + boolType: Type.vec(4, Type.bool), cases: [ { input: [a, b, vec4(F, F, F, F)], expected: vec4(a.x, a.y, a.z, a.w) }, { input: [a, b, vec4(F, F, F, T)], expected: vec4(a.x, a.y, a.z, b.w) }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts index 7872377dc42c..f7d2e3ccfd5a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sign.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'sign' builtin function -S is AbstractFloat, AbstractInt, i32, f32, f16 +S is abstract-float, Type.abstractInt, i32, f32, f16 T is S or vecN @const fn sign(e: T ) -> T Returns the sign of e. Component-wise when T is a vector. @@ -9,13 +9,7 @@ Returns the sign of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { - TypeAbstractFloat, - TypeAbstractInt, - TypeF16, - TypeF32, - TypeI32, -} from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, abstractIntBuiltin, builtin } from './builtin.js'; @@ -36,8 +30,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('sign'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -53,7 +47,7 @@ g.test('abstract_int') ) .fn(async t => { const cases = await d.get('abstract_int'); - await run(t, abstractIntBuiltin('sign'), [TypeAbstractInt], TypeAbstractInt, t.params, cases); + await run(t, abstractIntBuiltin('sign'), [Type.abstractInt], Type.abstractInt, t.params, cases); }); g.test('i32') @@ -64,7 +58,7 @@ g.test('i32') ) .fn(async t => { const cases = await d.get('i32'); - await run(t, builtin('sign'), [TypeI32], TypeI32, t.params, cases); + await run(t, builtin('sign'), [Type.i32], Type.i32, t.params, cases); }); g.test('f32') @@ -75,7 +69,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('sign'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('sign'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -89,5 +83,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('sign'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('sign'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts index e9420fc0880d..4d649b4db5eb 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sin.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'sin' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn sin(e: T ) -> T Returns the sine of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the sine of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -39,7 +39,7 @@ TODO(#792): Decide what the ground-truth is for these tests. [1] ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('sin'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('sin'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -53,5 +53,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('sin'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('sin'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts index 0070befa47fc..f59616d9af12 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sinh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'sinh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn sinh(e: T ) -> T Returns the hyperbolic sine of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the hyperbolic sine of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('sinh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('sinh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('sinh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('sinh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts index a32c112b8a94..1404061d02f7 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/smoothstep.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'smoothstep' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn smoothstep(low: T , high: T , x: T ) -> T Returns the smooth Hermite interpolation between 0 and 1. @@ -11,7 +11,7 @@ For scalar T, the result is t * t * (3.0 - 2.0 * t), where t = clamp((x - low) / import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -35,7 +35,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('smoothstep'), [TypeF32, TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('smoothstep'), [Type.f32, Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -49,5 +49,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('smoothstep'), [TypeF16, TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('smoothstep'), [Type.f16, Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts index cfd379fea660..ee4197d70f7d 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/sqrt.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'sqrt' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn sqrt(e: T ) -> T Returns the square root of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the square root of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, builtin('sqrt'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('sqrt'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f16_const' : 'f16_non_const'); - await run(t, builtin('sqrt'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('sqrt'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts index c55a48812e9c..caf75e6f623a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/step.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'step' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn step(edge: T ,x: T ) -> T Returns 1.0 if edge ≤ x, and 0.0 otherwise. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns 1.0 if edge ≤ x, and 0.0 otherwise. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('step'), [TypeF32, TypeF32], TypeF32, t.params, cases); + await run(t, builtin('step'), [Type.f32, Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('step'), [TypeF16, TypeF16], TypeF16, t.params, cases); + await run(t, builtin('step'), [Type.f16, Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts index f86b3c959a16..4ddef19fe168 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/tan.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'tan' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn tan(e: T ) -> T Returns the tangent of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the tangent of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('tan'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('tan'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('tan'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('tan'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts index 496c7bcf1b11..19f4ff55318b 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/tanh.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'tanh' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn tanh(e: T ) -> T Returns the hyperbolic tangent of e. Component-wise when T is a vector. @@ -9,7 +9,7 @@ Returns the hyperbolic tangent of e. Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -33,7 +33,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('tanh'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('tanh'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -47,5 +47,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('tanh'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('tanh'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/transpose.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/transpose.spec.ts index 90fa226a01e3..7a96906cfa71 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/transpose.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/transpose.spec.ts @@ -1,14 +1,14 @@ export const description = ` Execution tests for the 'transpose' builtin function -T is AbstractFloat, f32, or f16 +T is abstract-float, f32, or f16 @const transpose(e: matRxC ) -> matCxR Returns the transpose of e. `; import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32, TypeMat } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -32,8 +32,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('transpose'), - [TypeMat(cols, rows, TypeAbstractFloat)], - TypeMat(rows, cols, TypeAbstractFloat), + [Type.mat(cols, rows, Type.abstractFloat)], + Type.mat(rows, cols, Type.abstractFloat), t.params, cases ); @@ -59,8 +59,8 @@ g.test('f32') await run( t, builtin('transpose'), - [TypeMat(cols, rows, TypeF32)], - TypeMat(rows, cols, TypeF32), + [Type.mat(cols, rows, Type.f32)], + Type.mat(rows, cols, Type.f32), t.params, cases ); @@ -89,8 +89,8 @@ g.test('f16') await run( t, builtin('transpose'), - [TypeMat(cols, rows, TypeF16)], - TypeMat(rows, cols, TypeF16), + [Type.mat(cols, rows, Type.f16)], + Type.mat(rows, cols, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts index 022248ae5b97..9d05709fc686 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/trunc.spec.ts @@ -1,7 +1,7 @@ export const description = ` Execution tests for the 'trunc' builtin function -S is AbstractFloat, f32, f16 +S is abstract-float, f32, f16 T is S or vecN @const fn trunc(e: T ) -> T Returns the nearest whole number whose absolute value is less than or equal to e. @@ -10,7 +10,7 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; import { abstractFloatBuiltin, builtin } from './builtin.js'; @@ -31,8 +31,8 @@ g.test('abstract_float') await run( t, abstractFloatBuiltin('trunc'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases ); @@ -46,7 +46,7 @@ g.test('f32') ) .fn(async t => { const cases = await d.get('f32'); - await run(t, builtin('trunc'), [TypeF32], TypeF32, t.params, cases); + await run(t, builtin('trunc'), [Type.f32], Type.f32, t.params, cases); }); g.test('f16') @@ -60,5 +60,5 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, builtin('trunc'), [TypeF16], TypeF16, t.params, cases); + await run(t, builtin('trunc'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16float.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16float.spec.ts index da1819f8ef6e..e145afca50be 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16float.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16float.spec.ts @@ -7,7 +7,7 @@ interpretation of bits 16×i through 16×i+15 of e as an IEEE-754 binary16 value import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -25,5 +25,5 @@ g.test('unpack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('unpack2x16float'), [TypeU32], TypeVec(2, TypeF32), t.params, cases); + await run(t, builtin('unpack2x16float'), [Type.u32], Type.vec2f, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16snorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16snorm.spec.ts index a88702bcce70..059a5664f9e4 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16snorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16snorm.spec.ts @@ -7,7 +7,7 @@ of bits 16×i through 16×i+15 of e as a twos-complement signed integer. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -25,5 +25,5 @@ g.test('unpack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('unpack2x16snorm'), [TypeU32], TypeVec(2, TypeF32), t.params, cases); + await run(t, builtin('unpack2x16snorm'), [Type.u32], Type.vec2f, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16unorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16unorm.spec.ts index 325e0a9735b5..971f384023ef 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack2x16unorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack2x16unorm.spec.ts @@ -7,7 +7,7 @@ Component i of the result is v ÷ 65535, where v is the interpretation of bits import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -25,5 +25,5 @@ g.test('unpack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('unpack2x16unorm'), [TypeU32], TypeVec(2, TypeF32), t.params, cases); + await run(t, builtin('unpack2x16unorm'), [Type.u32], Type.vec2f, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack4x8snorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack4x8snorm.spec.ts index 3b48cca4539f..d6e533621b14 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack4x8snorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack4x8snorm.spec.ts @@ -7,7 +7,7 @@ bits 8×i through 8×i+7 of e as a twos-complement signed integer. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -25,5 +25,5 @@ g.test('unpack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('unpack4x8snorm'), [TypeU32], TypeVec(4, TypeF32), t.params, cases); + await run(t, builtin('unpack4x8snorm'), [Type.u32], Type.vec4f, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack4x8unorm.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack4x8unorm.spec.ts index 3e57f2592ee5..026043da1a97 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack4x8unorm.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack4x8unorm.spec.ts @@ -7,7 +7,7 @@ through 8×i+7 of e as an unsigned integer. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeU32, TypeVec } from '../../../../../util/conversion.js'; +import { Type } from '../../../../../util/conversion.js'; import { allInputSources, run } from '../../expression.js'; import { builtin } from './builtin.js'; @@ -25,5 +25,5 @@ g.test('unpack') .params(u => u.combine('inputSource', allInputSources)) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, builtin('unpack4x8unorm'), [TypeU32], TypeVec(4, TypeF32), t.params, cases); + await run(t, builtin('unpack4x8unorm'), [Type.u32], Type.vec4f, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack4xI8.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack4xI8.spec.ts index 6253ad7bebca..4f7e4ed3a70d 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack4xI8.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack4xI8.spec.ts @@ -8,7 +8,7 @@ with sign extension. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeI32, TypeU32, TypeVec, u32, toVector, i32 } from '../../../../../util/conversion.js'; +import { u32, toVector, i32, Type } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -52,5 +52,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('unpack4xI8'), [TypeU32], TypeVec(4, TypeI32), cfg, cases); + await run(t, builtin('unpack4xI8'), [Type.u32], Type.vec4i, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/unpack4xU8.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/unpack4xU8.spec.ts index 3c13f32fecc6..09849030eb10 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/unpack4xU8.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/unpack4xU8.spec.ts @@ -8,7 +8,7 @@ with zero extension. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeU32, TypeVec, u32, toVector } from '../../../../../util/conversion.js'; +import { u32, toVector, Type } from '../../../../../util/conversion.js'; import { Case } from '../../case.js'; import { allInputSources, Config, run } from '../../expression.js'; @@ -44,5 +44,5 @@ g.test('basic') return [makeCase(v)]; }); - await run(t, builtin('unpack4xU8'), [TypeU32], TypeVec(4, TypeU32), cfg, cases); + await run(t, builtin('unpack4xU8'), [Type.u32], Type.vec4u, cfg, cases); }); diff --git a/src/webgpu/shader/execution/expression/case.ts b/src/webgpu/shader/execution/expression/case.ts index 1cbde7be754f..063b58da4267 100644 --- a/src/webgpu/shader/execution/expression/case.ts +++ b/src/webgpu/shader/execution/expression/case.ts @@ -1,11 +1,20 @@ +import { crc32 } from '../../../../common/util/crc32.js'; import { ROArrayArray } from '../../../../common/util/types.js'; -import { ScalarBuilder, Value, Vector, i32, u32, abstractInt } from '../../../util/conversion.js'; +import { assert } from '../../../../common/util/util.js'; +import { + abstractInt, + i32, + ScalarBuilder, + u32, + Value, + VectorValue, +} from '../../../util/conversion.js'; import { - QuantizeFunc, cartesianProduct, + QuantizeFunc, quantizeToI32, - quantizeToU32, quantizeToI64, + quantizeToU32, } from '../../../util/math.js'; import { Expectation } from './expectation.js'; @@ -22,8 +31,46 @@ export type Case = { expected: Expectation; }; -/** CaseList is a list of Cases */ -export type CaseList = Array; +/** + * Filters a given set of Cases down to a target number of cases by + * randomly selecting which Cases to return. + * + * The selection algorithm is deterministic and stable for a case's + * inputs. + * + * This means that if a specific case is selected is not affected by the + * presence of other cases in the list, so in theory it is possible to create a + * pathological set of cases such that all or not of the cases are selected + * in spite of the target number. + * + * This is a trade-off from guaranteeing stability of the selected cases over + * small changes, so the target number of cases is more of a suggestion. It is + * still guaranteed that if you set n0 < n1, then the invocation with n0 will + * return at most the number of cases that n1 does, it just isn't guaranteed to + * be less. + * + * @param dis is a string provided for additional hashing information to avoid + * systemic bias in the selection process across different test + * suites. Specifically every Case with the same input values being + * included or skipped regardless of the operation that they are + * testing. This string should be something like the name of the case + * cache the values are for or the operation under test. + * @param n number of cases targeted be returned. Expected to be a positive + * integer. If equal or greater than the number of cases, then all the + * cases are returned. 0 is not allowed, since it is likely a + * programming error, because if the caller intentionally wants 0 + * items, they can just use []. + * @param cases list of Cases to be selected from. + */ +export function selectNCases(dis: string, n: number, cases: Case[]): Case[] { + assert(n > 0 && Math.round(n) === n, `n ${n} is expected to be a positive integer`); + const count = cases.length; + if (n >= count) { + return cases; + } + const dis_crc32 = crc32(dis); + return cases.filter(c => n * (0xffff_ffff / count) > (crc32(c.input.toString()) ^ dis_crc32)); +} /** * A function that performs a binary operation on x and y, and returns the @@ -63,8 +110,8 @@ function makeScalarVectorBinaryToVectorCase( return undefined; } return { - input: [scalarize(scalar), new Vector(vector.map(scalarize))], - expected: new Vector(result.filter(notUndefined).map(scalarize)), + input: [scalarize(scalar), new VectorValue(vector.map(scalarize))], + expected: new VectorValue(result.filter(notUndefined).map(scalarize)), }; } @@ -114,8 +161,8 @@ function makeVectorScalarBinaryToVectorCase( return undefined; } return { - input: [new Vector(vector.map(scalarize)), scalarize(scalar)], - expected: new Vector(result.filter(notUndefined).map(scalarize)), + input: [new VectorValue(vector.map(scalarize)), scalarize(scalar)], + expected: new VectorValue(result.filter(notUndefined).map(scalarize)), }; } @@ -317,8 +364,8 @@ function makeVectorVectorToScalarCase( return { input: [ - new Vector(param0_quantized.map(scalarize)), - new Vector(param1_quantized.map(scalarize)), + new VectorValue(param0_quantized.map(scalarize)), + new VectorValue(param1_quantized.map(scalarize)), ], expected: scalarize(result), }; diff --git a/src/webgpu/shader/execution/expression/case_cache.ts b/src/webgpu/shader/execution/expression/case_cache.ts index 1580cf3298ca..345183c5d506 100644 --- a/src/webgpu/shader/execution/expression/case_cache.ts +++ b/src/webgpu/shader/execution/expression/case_cache.ts @@ -3,11 +3,11 @@ import { unreachable } from '../../../../common/util/util.js'; import BinaryStream from '../../../util/binary_stream.js'; import { deserializeComparator, serializeComparator } from '../../../util/compare.js'; import { - Matrix, - Scalar, + MatrixValue, Value, - Vector, + VectorValue, deserializeValue, + isScalarValue, serializeValue, } from '../../../util/conversion.js'; import { @@ -17,7 +17,7 @@ import { } from '../../../util/floating_point.js'; import { flatten2DArray, unflatten2DArray } from '../../../util/math.js'; -import { Case, CaseList } from './case.js'; +import { Case } from './case.js'; import { Expectation, isComparator } from './expectation.js'; enum SerializedExpectationKind { @@ -31,7 +31,7 @@ enum SerializedExpectationKind { /** serializeExpectation() serializes an Expectation to a BinaryStream */ export function serializeExpectation(s: BinaryStream, e: Expectation) { - if (e instanceof Scalar || e instanceof Vector || e instanceof Matrix) { + if (isScalarValue(e) || e instanceof VectorValue || e instanceof MatrixValue) { s.writeU8(SerializedExpectationKind.Value); serializeValue(s, e); return; @@ -123,15 +123,15 @@ export function deserializeCase(s: BinaryStream): Case { return { input, expected }; } -/** CaseListBuilder is a function that builds a CaseList */ -export type CaseListBuilder = () => CaseList; +/** CaseListBuilder is a function that builds a list of cases, Case[] */ +export type CaseListBuilder = () => Case[]; /** - * CaseCache is a cache of CaseList. + * CaseCache is a cache of Case[]. * CaseCache implements the Cacheable interface, so the cases can be pre-built * and stored in the data cache, reducing computation costs at CTS runtime. */ -export class CaseCache implements Cacheable> { +export class CaseCache implements Cacheable> { /** * Constructor * @param name the name of the cache. This must be globally unique. @@ -143,7 +143,7 @@ export class CaseCache implements Cacheable> { } /** get() returns the list of cases with the given name */ - public async get(name: string): Promise { + public async get(name: string): Promise { const data = await dataCache.fetch(this); return data[name]; } @@ -152,8 +152,8 @@ export class CaseCache implements Cacheable> { * build() implements the Cacheable.build interface. * @returns the data. */ - build(): Promise> { - const built: Record = {}; + build(): Promise> { + const built: Record = {}; for (const name in this.builders) { const cases = this.builders[name](); built[name] = cases; @@ -165,7 +165,7 @@ export class CaseCache implements Cacheable> { * serialize() implements the Cacheable.serialize interface. * @returns the serialized data. */ - serialize(data: Record): Uint8Array { + serialize(data: Record): Uint8Array { const maxSize = 32 << 20; // 32MB - max size for a file const stream = new BinaryStream(new ArrayBuffer(maxSize)); stream.writeU32(Object.keys(data).length); @@ -180,9 +180,9 @@ export class CaseCache implements Cacheable> { * deserialize() implements the Cacheable.deserialize interface. * @returns the deserialize data. */ - deserialize(array: Uint8Array): Record { + deserialize(array: Uint8Array): Record { const s = new BinaryStream(array.buffer); - const casesByName: Record = {}; + const casesByName: Record = {}; const numRecords = s.readU32(); for (let i = 0; i < numRecords; i++) { const name = s.readString(); diff --git a/src/webgpu/shader/execution/expression/expectation.ts b/src/webgpu/shader/execution/expression/expectation.ts index 8078673f2569..d43ab5279116 100644 --- a/src/webgpu/shader/execution/expression/expectation.ts +++ b/src/webgpu/shader/execution/expression/expectation.ts @@ -1,6 +1,6 @@ import { ROArrayArray } from '../../../../common/util/types.js'; import { Comparator, compare } from '../../../util/compare.js'; -import { Matrix, Scalar, Value, Vector } from '../../../util/conversion.js'; +import { MatrixValue, Value, VectorValue, isScalarValue } from '../../../util/conversion.js'; import { FPInterval } from '../../../util/floating_point.js'; export type Expectation = @@ -14,9 +14,9 @@ export type Expectation = export function isComparator(e: Expectation): e is Comparator { return !( e instanceof FPInterval || - e instanceof Scalar || - e instanceof Vector || - e instanceof Matrix || + isScalarValue(e) || + e instanceof VectorValue || + e instanceof MatrixValue || e instanceof Array ); } diff --git a/src/webgpu/shader/execution/expression/expression.ts b/src/webgpu/shader/execution/expression/expression.ts index 3eda441681a7..21e1d40eab90 100644 --- a/src/webgpu/shader/execution/expression/expression.ts +++ b/src/webgpu/shader/execution/expression/expression.ts @@ -5,19 +5,17 @@ import { Comparator, ComparatorImpl } from '../../../util/compare.js'; import { kValue } from '../../../util/constants.js'; import { MatrixType, - Scalar, + ScalarValue, ScalarType, Type, - TypeU32, - TypeVec, - Value, - Vector, VectorType, + Value, + VectorValue, isAbstractType, scalarTypeOf, } from '../../../util/conversion.js'; -import { Case, CaseList } from './case.js'; +import { Case } from './case.js'; import { toComparator } from './expectation.js'; /** The input value source */ @@ -158,11 +156,11 @@ function storageType(ty: Type): Type { `Custom handling is implemented for 'abstract-float' values` ); if (ty.kind === 'bool') { - return TypeU32; + return Type.u32; } } if (ty instanceof VectorType) { - return TypeVec(ty.width, storageType(ty.elementType) as ScalarType); + return Type.vec(ty.width, storageType(ty.elementType) as ScalarType); } return ty; } @@ -267,7 +265,7 @@ export async function run( parameterTypes: Array, resultType: Type, cfg: Config = { inputSource: 'storage_r' }, - cases: CaseList, + cases: Case[], batch_size?: number ) { // If the 'vectorize' config option was provided, pack the cases into vectors. @@ -324,7 +322,7 @@ export async function run( } }; - const processBatch = async (batchCases: CaseList) => { + const processBatch = async (batchCases: Case[]) => { const checkBatch = await submitBatch( t, shaderBuilder, @@ -375,7 +373,7 @@ async function submitBatch( shaderBuilder: ShaderBuilder, parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource, pipelineCache: PipelineCache ): Promise<() => void> { @@ -469,7 +467,7 @@ function map(v: T | readonly T[], fn: (value: T, index?: number) => U): U[ export type ShaderBuilder = ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => string; @@ -536,7 +534,7 @@ struct Output { function wgslValuesArray( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], expressionBuilder: ExpressionBuilder ): string { return ` @@ -586,7 +584,7 @@ function basicExpressionShaderBody( expressionBuilder: ExpressionBuilder, parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ): string { assert( @@ -683,7 +681,7 @@ export function basicExpressionBuilder(expressionBuilder: ExpressionBuilder): Sh return ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => { return `\ @@ -706,7 +704,7 @@ export function basicExpressionWithPredeclarationBuilder( return ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => { return `\ @@ -726,7 +724,7 @@ export function compoundAssignmentBuilder(op: string): ShaderBuilder { return ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => { ////////////////////////////////////////////////////////////////////////// @@ -953,7 +951,7 @@ export function abstractFloatShaderBuilder(expressionBuilder: ExpressionBuilder) return ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => { assert(inputSource === 'const', `'abstract-float' results are only defined for const-eval`); @@ -1037,7 +1035,7 @@ export function abstractIntShaderBuilder(expressionBuilder: ExpressionBuilder): return ( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource ) => { assert(inputSource === 'const', `'abstract-int' results are only defined for const-eval`); @@ -1084,7 +1082,7 @@ async function buildPipeline( shaderBuilder: ShaderBuilder, parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], inputSource: InputSource, outputBuffer: GPUBuffer, pipelineCache: PipelineCache @@ -1194,9 +1192,9 @@ async function buildPipeline( function packScalarsToVector( parameterTypes: Array, resultType: Type, - cases: CaseList, + cases: Case[], vectorWidth: number -): { cases: CaseList; parameterTypes: Array; resultType: Type } { +): { cases: Case[]; parameterTypes: Array; resultType: Type } { // Validate that the parameters and return type are all vectorizable for (let i = 0; i < parameterTypes.length; i++) { const ty = parameterTypes[i]; @@ -1213,22 +1211,22 @@ function packScalarsToVector( } const packedCases: Array = []; - const packedParameterTypes = parameterTypes.map(p => TypeVec(vectorWidth, p as ScalarType)); - const packedResultType = new VectorType(vectorWidth, resultType); + const packedParameterTypes = parameterTypes.map(p => Type.vec(vectorWidth, p as ScalarType)); + const packedResultType = Type.vec(vectorWidth, resultType); const clampCaseIdx = (idx: number) => Math.min(idx, cases.length - 1); let caseIdx = 0; while (caseIdx < cases.length) { // Construct the vectorized inputs from the scalar cases - const packedInputs = new Array(parameterTypes.length); + const packedInputs = new Array(parameterTypes.length); for (let paramIdx = 0; paramIdx < parameterTypes.length; paramIdx++) { - const inputElements = new Array(vectorWidth); + const inputElements = new Array(vectorWidth); for (let i = 0; i < vectorWidth; i++) { const input = cases[clampCaseIdx(caseIdx + i)].input; - inputElements[i] = (input instanceof Array ? input[paramIdx] : input) as Scalar; + inputElements[i] = (input instanceof Array ? input[paramIdx] : input) as ScalarValue; } - packedInputs[paramIdx] = new Vector(inputElements); + packedInputs[paramIdx] = new VectorValue(inputElements); } // Gather the comparators for the packed cases @@ -1242,7 +1240,7 @@ function packScalarsToVector( const gElements = new Array(vectorWidth); const eElements = new Array(vectorWidth); for (let i = 0; i < vectorWidth; i++) { - const d = cmp_impls[i]((got as Vector).elements[i]); + const d = cmp_impls[i]((got as VectorValue).elements[i]); matched = matched && d.matched; gElements[i] = d.got; eElements[i] = d.expected; diff --git a/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts index 005ddc6448ea..686d4b7c4ac2 100644 --- a/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/af_arithmetic.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for AbstractFloat arithmetic unary expression operations +Execution Tests for Type.abstractFloat arithmetic unary expression operations `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './af_arithmetic.cache.js'; @@ -30,8 +30,8 @@ Accuracy: Correctly rounded await run( t, abstractFloatUnary('-'), - [TypeAbstractFloat], - TypeAbstractFloat, + [Type.abstractFloat], + Type.abstractFloat, t.params, cases, 1 diff --git a/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts b/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts index 76e96fe80354..001c47e117bd 100644 --- a/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/af_assignment.spec.ts @@ -4,7 +4,7 @@ Execution Tests for assignment of AbstractFloats import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractFloat, TypeF16, TypeF32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, abstractFloatShaderBuilder, @@ -35,7 +35,15 @@ testing that extracting abstract floats works .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('abstract'); - await run(t, abstract_assignment(), [TypeAbstractFloat], TypeAbstractFloat, t.params, cases, 1); + await run( + t, + abstract_assignment(), + [Type.abstractFloat], + Type.abstractFloat, + t.params, + cases, + 1 + ); }); g.test('f32') @@ -48,7 +56,7 @@ concretizing to f32 .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('f32'); - await run(t, concrete_assignment(), [TypeAbstractFloat], TypeF32, t.params, cases); + await run(t, concrete_assignment(), [Type.abstractFloat], Type.f32, t.params, cases); }); g.test('f16') @@ -64,5 +72,5 @@ concretizing to f16 .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('f16'); - await run(t, concrete_assignment(), [TypeAbstractFloat], TypeF16, t.params, cases); + await run(t, concrete_assignment(), [Type.abstractFloat], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/ai_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/ai_arithmetic.spec.ts index bc50be4a7b62..625a38b2d5af 100644 --- a/src/webgpu/shader/execution/expression/unary/ai_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/ai_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the abstract integer arithmetic unary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractInt } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { onlyConstInputSource, run } from '../expression.js'; import { d } from './ai_arithmetic.cache.js'; @@ -26,5 +26,5 @@ Expression: -x ) .fn(async t => { const cases = await d.get('negation'); - await run(t, abstractIntUnary('-'), [TypeAbstractInt], TypeAbstractInt, t.params, cases); + await run(t, abstractIntUnary('-'), [Type.abstractInt], Type.abstractInt, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/ai_assignment.spec.ts b/src/webgpu/shader/execution/expression/unary/ai_assignment.spec.ts index f7915df97adc..fe1ba2d9fc12 100644 --- a/src/webgpu/shader/execution/expression/unary/ai_assignment.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/ai_assignment.spec.ts @@ -4,7 +4,7 @@ Execution Tests for assignment of AbstractInts import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeAbstractInt, TypeI32, TypeU32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, abstractIntShaderBuilder, @@ -35,7 +35,7 @@ testing that extracting abstract ints works .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('abstract'); - await run(t, abstract_assignment(), [TypeAbstractInt], TypeAbstractInt, t.params, cases, 1); + await run(t, abstract_assignment(), [Type.abstractInt], Type.abstractInt, t.params, cases, 1); }); g.test('i32') @@ -48,7 +48,7 @@ concretizing to i32 .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('i32'); - await run(t, concrete_assignment(), [TypeAbstractInt], TypeI32, t.params, cases); + await run(t, concrete_assignment(), [Type.abstractInt], Type.i32, t.params, cases); }); g.test('u32') @@ -61,5 +61,5 @@ concretizing to u32 .params(u => u.combine('inputSource', onlyConstInputSource)) .fn(async t => { const cases = await d.get('u32'); - await run(t, concrete_assignment(), [TypeAbstractInt], TypeU32, t.params, cases); + await run(t, concrete_assignment(), [Type.abstractInt], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/ai_complement.spec.ts b/src/webgpu/shader/execution/expression/unary/ai_complement.spec.ts index 919321e207ce..507ae219cb29 100644 --- a/src/webgpu/shader/execution/expression/unary/ai_complement.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/ai_complement.spec.ts @@ -1,10 +1,10 @@ export const description = ` -Execution Tests for the AbstractInt bitwise complement operation +Execution Tests for the Type.abstractInt bitwise complement operation `; import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { abstractInt, TypeAbstractInt } from '../../../../util/conversion.js'; +import { abstractInt, Type } from '../../../../util/conversion.js'; import { fullI64Range } from '../../../../util/math.js'; import { onlyConstInputSource, run } from '../expression.js'; @@ -28,5 +28,5 @@ Expression: ~x const cases = fullI64Range().map(e => { return { input: abstractInt(e), expected: abstractInt(~e) }; }); - await run(t, abstractIntUnary('~'), [TypeAbstractInt], TypeAbstractInt, t.params, cases); + await run(t, abstractIntUnary('~'), [Type.abstractInt], Type.abstractInt, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/bool_conversion.cache.ts b/src/webgpu/shader/execution/expression/unary/bool_conversion.cache.ts index f64ec1cd4180..5b16c49c421b 100644 --- a/src/webgpu/shader/execution/expression/unary/bool_conversion.cache.ts +++ b/src/webgpu/shader/execution/expression/unary/bool_conversion.cache.ts @@ -1,5 +1,5 @@ import { anyOf } from '../../../../util/compare.js'; -import { Scalar, bool, f16, f32, i32, u32 } from '../../../../util/conversion.js'; +import { ScalarValue, bool, f16, f32, i32, u32 } from '../../../../util/conversion.js'; import { fullI32Range, fullU32Range, @@ -29,7 +29,7 @@ export const d = makeCaseCache('unary/bool_conversion', { }, f32: () => { return scalarF32Range().map(f => { - const expected: Scalar[] = []; + const expected: ScalarValue[] = []; if (f !== 0) { expected.push(bool(true)); } @@ -41,7 +41,7 @@ export const d = makeCaseCache('unary/bool_conversion', { }, f16: () => { return scalarF16Range().map(f => { - const expected: Scalar[] = []; + const expected: ScalarValue[] = []; if (f !== 0) { expected.push(bool(true)); } diff --git a/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts index 5f5bb31397a3..55d01d3eda1f 100644 --- a/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/bool_conversion.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the boolean conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeF16, TypeF32, TypeI32, TypeU32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, run } from '../expression.js'; import { d } from './bool_conversion.cache.js'; @@ -31,7 +31,14 @@ Identity operation ) .fn(async t => { const cases = await d.get('bool'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeBool, t.params, cases); + await run( + t, + vectorizeToExpression(t.params.vectorize), + [Type.bool], + Type.bool, + t.params, + cases + ); }); g.test('u32') @@ -49,7 +56,7 @@ The result is false if e is 0, and true otherwise. ) .fn(async t => { const cases = await d.get('u32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeBool, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.bool, t.params, cases); }); g.test('i32') @@ -67,7 +74,7 @@ The result is false if e is 0, and true otherwise. ) .fn(async t => { const cases = await d.get('i32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeBool, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.bool, t.params, cases); }); g.test('f32') @@ -85,7 +92,7 @@ The result is false if e is 0.0 or -0.0, and true otherwise. ) .fn(async t => { const cases = await d.get('f32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeBool, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.bool, t.params, cases); }); g.test('f16') @@ -106,5 +113,5 @@ The result is false if e is 0.0 or -0.0, and true otherwise. }) .fn(async t => { const cases = await d.get('f16'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeBool, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/bool_logical.spec.ts b/src/webgpu/shader/execution/expression/unary/bool_logical.spec.ts index 01eaaab43a51..58d4b9fc0fc3 100644 --- a/src/webgpu/shader/execution/expression/unary/bool_logical.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/bool_logical.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the boolean unary logical expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { bool, TypeBool } from '../../../../util/conversion.js'; +import { bool, Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { unary } from './unary.js'; @@ -29,5 +29,5 @@ Logical negation. The result is true when e is false and false when e is true. C { input: bool(false), expected: bool(true) }, ]; - await run(t, unary('!'), [TypeBool], TypeBool, t.params, cases); + await run(t, unary('!'), [Type.bool], Type.bool, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts index 60e16e645221..813bbf7a64e6 100644 --- a/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f16_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the f16 arithmetic unary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF16 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { d } from './f16_arithmetic.cache.js'; @@ -28,5 +28,5 @@ Accuracy: Correctly rounded }) .fn(async t => { const cases = await d.get('negation'); - await run(t, unary('-'), [TypeF16], TypeF16, t.params, cases); + await run(t, unary('-'), [Type.f16], Type.f16, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts index a8da8ff3bd7f..765b36d54cc6 100644 --- a/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f16_conversion.spec.ts @@ -4,14 +4,7 @@ Execution Tests for the f32 conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { - TypeBool, - TypeF16, - TypeF32, - TypeI32, - TypeMat, - TypeU32, -} from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, run } from '../expression.js'; import { d } from './f16_conversion.cache.js'; @@ -46,7 +39,7 @@ The result is 1.0 if e is true and 0.0 otherwise }) .fn(async t => { const cases = await d.get('bool'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeF16, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.bool], Type.f16, t.params, cases); }); g.test('u32') @@ -66,7 +59,7 @@ Converted to f16, +/-Inf if out of range }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'u32_const' : 'u32_non_const'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeF16, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.f16, t.params, cases); }); g.test('i32') @@ -86,7 +79,7 @@ Converted to f16, +/-Inf if out of range }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'i32_const' : 'i32_non_const'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeF16, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.f16, t.params, cases); }); g.test('f32') @@ -106,7 +99,7 @@ Correctly rounded to f16 }) .fn(async t => { const cases = await d.get(t.params.inputSource === 'const' ? 'f32_const' : 'f32_non_const'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeF16, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.f16, t.params, cases); }); g.test('f32_mat') @@ -132,8 +125,8 @@ g.test('f32_mat') await run( t, matrixExperession(cols, rows), - [TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f16), t.params, cases ); @@ -156,7 +149,7 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeF16, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.f16, t.params, cases); }); g.test('f16_mat') @@ -182,8 +175,8 @@ g.test('f16_mat') await run( t, matrixExperession(cols, rows), - [TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF16), + [Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f16), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts index c60e2c3d51b0..3bb48705e854 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the f32 arithmetic unary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeF32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { d } from './f32_arithmetic.cache.js'; @@ -25,5 +25,5 @@ Accuracy: Correctly rounded ) .fn(async t => { const cases = await d.get('negation'); - await run(t, unary('-'), [TypeF32], TypeF32, t.params, cases); + await run(t, unary('-'), [Type.f32], Type.f32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts index 3e2fbd540ace..464fdee44e79 100644 --- a/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/f32_conversion.spec.ts @@ -4,14 +4,7 @@ Execution Tests for the f32 conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { - TypeBool, - TypeF16, - TypeF32, - TypeI32, - TypeMat, - TypeU32, -} from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, run } from '../expression.js'; import { d } from './f32_conversion.cache.js'; @@ -43,7 +36,7 @@ The result is 1.0 if e is true and 0.0 otherwise ) .fn(async t => { const cases = await d.get('bool'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeF32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.bool], Type.f32, t.params, cases); }); g.test('u32') @@ -60,7 +53,7 @@ Converted to f32 ) .fn(async t => { const cases = await d.get('u32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeF32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.f32, t.params, cases); }); g.test('i32') @@ -77,7 +70,7 @@ Converted to f32 ) .fn(async t => { const cases = await d.get('i32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeF32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.f32, t.params, cases); }); g.test('f32') @@ -94,7 +87,7 @@ Identity operation ) .fn(async t => { const cases = await d.get('f32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeF32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.f32, t.params, cases); }); g.test('f32_mat') @@ -117,8 +110,8 @@ g.test('f32_mat') await run( t, matrixExperession(cols, rows), - [TypeMat(cols, rows, TypeF32)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f32)], + Type.mat(cols, rows, Type.f32), t.params, cases ); @@ -141,7 +134,7 @@ g.test('f16') }) .fn(async t => { const cases = await d.get('f16'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeF32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.f32, t.params, cases); }); g.test('f16_mat') @@ -167,8 +160,8 @@ g.test('f16_mat') await run( t, matrixExperession(cols, rows), - [TypeMat(cols, rows, TypeF16)], - TypeMat(cols, rows, TypeF32), + [Type.mat(cols, rows, Type.f16)], + Type.mat(cols, rows, Type.f32), t.params, cases ); diff --git a/src/webgpu/shader/execution/expression/unary/i32_arithmetic.spec.ts b/src/webgpu/shader/execution/expression/unary/i32_arithmetic.spec.ts index a6fe77ada165..a7d16a96cd88 100644 --- a/src/webgpu/shader/execution/expression/unary/i32_arithmetic.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/i32_arithmetic.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the i32 arithmetic unary expression operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeI32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { allInputSources, run } from '../expression.js'; import { d } from './i32_arithmetic.cache.js'; @@ -24,5 +24,5 @@ Expression: -x ) .fn(async t => { const cases = await d.get('negation'); - await run(t, unary('-'), [TypeI32], TypeI32, t.params, cases); + await run(t, unary('-'), [Type.i32], Type.i32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/i32_complement.spec.ts b/src/webgpu/shader/execution/expression/unary/i32_complement.spec.ts index dc0ca8b8d066..01e5728d70d1 100644 --- a/src/webgpu/shader/execution/expression/unary/i32_complement.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/i32_complement.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the i32 bitwise complement operation import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { i32, TypeI32 } from '../../../../util/conversion.js'; +import { i32, Type } from '../../../../util/conversion.js'; import { fullI32Range } from '../../../../util/math.js'; import { allInputSources, run } from '../expression.js'; @@ -26,5 +26,5 @@ Expression: ~x const cases = fullI32Range().map(e => { return { input: i32(e), expected: i32(~e) }; }); - await run(t, unary('~'), [TypeI32], TypeI32, t.params, cases); + await run(t, unary('~'), [Type.i32], Type.i32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts index 4ad3c4e7424f..606253b59e5c 100644 --- a/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/i32_conversion.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the i32 conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeF16, TypeF32, TypeI32, TypeU32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, run } from '../expression.js'; import { d } from './i32_conversion.cache.js'; @@ -31,7 +31,7 @@ The result is 1u if e is true and 0u otherwise ) .fn(async t => { const cases = await d.get('bool'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeI32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.bool], Type.i32, t.params, cases); }); g.test('u32') @@ -48,7 +48,7 @@ Reinterpretation of bits ) .fn(async t => { const cases = await d.get('u32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeI32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.i32, t.params, cases); }); g.test('i32') @@ -65,7 +65,7 @@ Identity operation ) .fn(async t => { const cases = await d.get('i32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeI32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.i32, t.params, cases); }); g.test('f32') @@ -82,7 +82,7 @@ e is converted to i32, rounding towards zero ) .fn(async t => { const cases = await d.get('f32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeI32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.i32, t.params, cases); }); g.test('f16') @@ -102,5 +102,5 @@ e is converted to u32, rounding towards zero }) .fn(async t => { const cases = await d.get('f16'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeI32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.i32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/u32_complement.spec.ts b/src/webgpu/shader/execution/expression/unary/u32_complement.spec.ts index 6052ac008f0e..74251a32c62b 100644 --- a/src/webgpu/shader/execution/expression/unary/u32_complement.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/u32_complement.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the u32 bitwise complement operation import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeU32, u32 } from '../../../../util/conversion.js'; +import { Type, u32 } from '../../../../util/conversion.js'; import { fullU32Range } from '../../../../util/math.js'; import { allInputSources, run } from '../expression.js'; @@ -26,5 +26,5 @@ Expression: ~x const cases = fullU32Range().map(e => { return { input: u32(e), expected: u32(~e) }; }); - await run(t, unary('~'), [TypeU32], TypeU32, t.params, cases); + await run(t, unary('~'), [Type.u32], Type.u32, t.params, cases); }); diff --git a/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts b/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts index d684824362cf..330f713dca5e 100644 --- a/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts +++ b/src/webgpu/shader/execution/expression/unary/u32_conversion.spec.ts @@ -4,7 +4,7 @@ Execution Tests for the u32 conversion operations import { makeTestGroup } from '../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../gpu_test.js'; -import { TypeBool, TypeF16, TypeF32, TypeI32, TypeU32 } from '../../../../util/conversion.js'; +import { Type } from '../../../../util/conversion.js'; import { ShaderBuilder, allInputSources, run } from '../expression.js'; import { d } from './u32_conversion.cache.js'; @@ -31,7 +31,7 @@ The result is 1u if e is true and 0u otherwise ) .fn(async t => { const cases = await d.get('bool'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeBool], TypeU32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.bool], Type.u32, t.params, cases); }); g.test('u32') @@ -48,7 +48,7 @@ Identity operation ) .fn(async t => { const cases = await d.get('u32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeU32], TypeU32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.u32], Type.u32, t.params, cases); }); g.test('i32') @@ -65,7 +65,7 @@ Reinterpretation of bits ) .fn(async t => { const cases = await d.get('i32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeI32], TypeU32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.i32], Type.u32, t.params, cases); }); g.test('f32') @@ -82,7 +82,7 @@ e is converted to u32, rounding towards zero ) .fn(async t => { const cases = await d.get('f32'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF32], TypeU32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f32], Type.u32, t.params, cases); }); g.test('f16') @@ -102,14 +102,14 @@ e is converted to u32, rounding towards zero }) .fn(async t => { const cases = await d.get('f16'); - await run(t, vectorizeToExpression(t.params.vectorize), [TypeF16], TypeU32, t.params, cases); + await run(t, vectorizeToExpression(t.params.vectorize), [Type.f16], Type.u32, t.params, cases); }); g.test('abstract_int') .specURL('https://www.w3.org/TR/WGSL/#value-constructor-builtin-function') .desc( ` -u32(e), where e is an AbstractInt +u32(e), where e is an Type.abstractInt Identity operation if the e can be represented in u32, otherwise it produces a shader-creation error ` diff --git a/src/webgpu/shader/execution/shader_io/user_io.spec.ts b/src/webgpu/shader/execution/shader_io/user_io.spec.ts new file mode 100644 index 000000000000..0c26f89872dc --- /dev/null +++ b/src/webgpu/shader/execution/shader_io/user_io.spec.ts @@ -0,0 +1,213 @@ +export const description = ` +Test for user-defined shader I/O. + +passthrough: + * Data passed into vertex shader as uints and converted to test type + * Passed from vertex to fragment as test type + * Output from fragment shader as uint +`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { range } from '../../../../common/util/util.js'; +import { GPUTest } from '../../../gpu_test.js'; + +export const g = makeTestGroup(GPUTest); + +function generateInterstagePassthroughCode(type: string): string { + return ` +${type === 'f16' ? 'enable f16;' : ''} +struct IOData { + @builtin(position) pos : vec4f, + @location(0) @interpolate(flat) user0 : ${type}, + @location(1) @interpolate(flat) user1 : vec2<${type}>, + @location(2) @interpolate(flat) user2 : vec4<${type}>, +} + +struct VertexInput { + @builtin(vertex_index) idx : u32, + @location(0) in0 : u32, + @location(1) in1 : vec2u, + @location(2) in2 : vec4u, +} + +@vertex +fn vsMain(input : VertexInput) -> IOData { + const vertices = array( + vec4f(-1, -1, 0, 1), + vec4f(-1, 1, 0, 1), + vec4f( 1, -1, 0, 1), + ); + var data : IOData; + data.pos = vertices[input.idx]; + data.user0 = ${type}(input.in0); + data.user1 = vec2<${type}>(input.in1); + data.user2 = vec4<${type}>(input.in2); + return data; +} + +struct FragOutput { + @location(0) out0 : u32, + @location(1) out1 : vec2u, + @location(2) out2 : vec4u, +} + +@fragment +fn fsMain(input : IOData) -> FragOutput { + var out : FragOutput; + out.out0 = u32(input.user0); + out.out1 = vec2u(input.user1); + out.out2 = vec4u(input.user2); + return out; +} +`; +} + +function drawPassthrough(t: GPUTest, code: string) { + // Default limit is 32 bytes of color attachments. + // These attachments use 28 bytes (which is why vec3 is skipped). + const formats: GPUTextureFormat[] = ['r32uint', 'rg32uint', 'rgba32uint']; + const components = [1, 2, 4]; + const pipeline = t.device.createRenderPipeline({ + layout: 'auto', + vertex: { + module: t.device.createShaderModule({ code }), + entryPoint: 'vsMain', + buffers: [ + { + arrayStride: 4, + attributes: [ + { + format: 'uint32', + offset: 0, + shaderLocation: 0, + }, + ], + }, + { + arrayStride: 8, + attributes: [ + { + format: 'uint32x2', + offset: 0, + shaderLocation: 1, + }, + ], + }, + { + arrayStride: 16, + attributes: [ + { + format: 'uint32x4', + offset: 0, + shaderLocation: 2, + }, + ], + }, + ], + }, + fragment: { + module: t.device.createShaderModule({ code }), + entryPoint: 'fsMain', + targets: formats.map(x => { + return { format: x }; + }), + }, + primitive: { + topology: 'triangle-list', + }, + }); + + const vertexBuffer = t.makeBufferWithContents( + new Uint32Array([ + // scalar: offset 0 + 1, 1, 1, 0, + // vec2: offset 16 + 2, 2, 2, 2, 2, 2, 0, 0, + // vec4: offset 48 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + ]), + GPUBufferUsage.COPY_SRC | GPUBufferUsage.VERTEX + ); + + const bytesPerComponent = 4; + // 256 is the minimum bytes per row for texture to buffer copies. + const width = 256 / bytesPerComponent; + const height = 2; + const copyWidth = 4; + const outputTextures = range(3, i => { + const texture = t.device.createTexture({ + size: [width, height], + usage: + GPUTextureUsage.COPY_SRC | + GPUTextureUsage.RENDER_ATTACHMENT | + GPUTextureUsage.TEXTURE_BINDING, + format: formats[i], + }); + t.trackForCleanup(texture); + return texture; + }); + + let bufferSize = 1; + for (const comp of components) { + bufferSize *= comp; + } + bufferSize *= outputTextures.length * bytesPerComponent * copyWidth; + const outputBuffer = t.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + }); + t.trackForCleanup(outputBuffer); + + const encoder = t.device.createCommandEncoder(); + const pass = encoder.beginRenderPass({ + colorAttachments: outputTextures.map(t => ({ + view: t.createView(), + loadOp: 'clear', + storeOp: 'store', + })), + }); + pass.setPipeline(pipeline); + pass.setVertexBuffer(0, vertexBuffer, 0, 12); + pass.setVertexBuffer(1, vertexBuffer, 16, 24); + pass.setVertexBuffer(2, vertexBuffer, 48, 48); + pass.draw(3); + pass.end(); + + // Copy 'copyWidth' samples from each attachment into a buffer to check the results. + let offset = 0; + let expectArray: number[] = []; + for (let i = 0; i < outputTextures.length; i++) { + encoder.copyTextureToBuffer( + { texture: outputTextures[i] }, + { + buffer: outputBuffer, + offset, + bytesPerRow: bytesPerComponent * components[i] * width, + rowsPerImage: height, + }, + { width: copyWidth, height: 1 } + ); + offset += components[i] * bytesPerComponent * copyWidth; + for (let j = 0; j < components[i]; j++) { + const value = i + 1; + expectArray = expectArray.concat([value, value, value, value]); + } + } + t.queue.submit([encoder.finish()]); + + const expect = new Uint32Array(expectArray); + t.expectGPUBufferValuesEqual(outputBuffer, expect); +} + +g.test('passthrough') + .desc('Tests passing user-defined data from vertex input through fragment output') + .params(u => u.combine('type', ['f32', 'f16', 'i32', 'u32'] as const)) + .beforeAllSubcases(t => { + if (t.params.type === 'f16') { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const code = generateInterstagePassthroughCode(t.params.type); + drawPassthrough(t, code); + }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/abs.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/abs.spec.ts index f09b47264f33..3fc9eeb22c3d 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/abs.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/abs.spec.ts @@ -5,12 +5,7 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; -import { - TypeF16, - elementType, - kAllFloatAndConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, -} from '../../../../../util/conversion.js'; +import { Type, kAllScalarsAndVectors, scalarTypeOf } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; import { @@ -22,10 +17,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatAndConcreteIntegerScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kAllScalarsAndVectors); g.test('values') .desc( @@ -42,7 +34,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() never .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -56,3 +48,107 @@ Validates that constant evaluation and override evaluation of ${builtin}() never t.params.stage ); }); + +const kTests = { + valid: { + src: `_ = abs(1);`, + pass: true, + }, + alias: { + src: `_ = abs(i32_alias(1));`, + pass: true, + }, + + bool: { + src: `_ = abs(false);`, + pass: false, + }, + vec_bool: { + src: `_ = abs(vec2(false, true));`, + pass: false, + }, + matrix: { + src: `_ = abs(mat2x2(1, 1, 1, 1));`, + pass: false, + }, + atomic: { + src: ` _ = abs(a);`, + pass: false, + }, + array: { + src: `var a: array; + _ = abs(a);`, + pass: false, + }, + array_runtime: { + src: `_ = abs(k.arry);`, + pass: false, + }, + struct: { + src: `var a: A; + _ = abs(a);`, + pass: false, + }, + enumerant: { + src: `_ = abs(read_write);`, + pass: false, + }, + ptr: { + src: `var a = 1u; + let p: ptr = &a; + _ = abs(p);`, + pass: false, + }, + ptr_deref: { + src: `var a = 1u; + let p: ptr = &a; + _ = abs(*p);`, + pass: true, + }, + sampler: { + src: `_ = abs(s);`, + pass: false, + }, + texture: { + src: `_ = abs(t);`, + pass: false, + }, + no_params: { + src: `_ = abs();`, + pass: false, + }, + too_many_params: { + src: `_ = abs(1, 2);`, + pass: false, + }, +}; + +g.test('parameters') + .desc(`Test that ${builtin} is validated correctly.`) + .params(u => u.combine('test', keysOf(kTests))) + .fn(t => { + const src = kTests[t.params.test].src; + const code = ` +alias i32_alias = i32; + +@group(0) @binding(0) var s: sampler; +@group(0) @binding(1) var t: texture_2d; + +var a: atomic; + +struct A { + i: u32, +} +struct B { + arry: array, +} +@group(0) @binding(3) var k: B; + + +@vertex +fn main() -> @builtin(position) vec4 { + ${src} + return vec4(.4, .2, .3, .1); +}`; + t.expectCompileResult(kTests[t.params.test].pass, code); + }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/acos.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/acos.spec.ts index 8883bd72e11c..9b6438aaec65 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/acos.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/acos.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { absBigInt } from '../../../../../util/math.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -27,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -52,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -71,7 +66,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec }); // f32 is included here to confirm that validation is failing due to a type issue and not something else. -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -85,7 +80,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/acosh.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/acosh.spec.ts index 29cb1aad44e1..c3644befc9ba 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/acosh.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/acosh.spec.ts @@ -6,14 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - TypeAbstractInt, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -29,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -54,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -63,7 +56,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.acosh(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -74,7 +67,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord(kAllConcreteIntegerScalarsAndVectors); +const kIntegerArgumentTypes = objectsToRecord(kConcreteIntegerScalarsAndVectors); g.test('integer_argument') .desc( @@ -88,8 +81,8 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, - [type.create(type === TypeAbstractInt ? 1n : 1)], + /* expectedResult */ type === Type.f32, + [type.create(type === Type.abstractInt ? 1n : 1)], 'constant' ); }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/asin.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/asin.spec.ts index 82f426035729..bff34f104dee 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/asin.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/asin.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { absBigInt } from '../../../../../util/math.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -27,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -52,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -70,7 +65,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -84,7 +79,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/asinh.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/asinh.spec.ts index 6cff91c384da..cec4b73c6094 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/asinh.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/asinh.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, + Type, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { linearRange, linearRangeBigInt } from '../../../../../util/math.js'; @@ -29,10 +26,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); const additionalRangeForType = rangeForType( linearRange(-2000, 2000, 10), @@ -56,7 +50,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -65,7 +59,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.asinh(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -76,7 +70,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -90,7 +84,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/atan.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/atan.spec.ts index 8ad4230bc58d..76bafbbcca8a 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/atan.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/atan.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +24,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -51,7 +46,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -67,7 +62,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -81,7 +76,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/atan2.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/atan2.spec.ts index 9bfefe287ffe..1a6776a018fa 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/atan2.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/atan2.spec.ts @@ -6,13 +6,11 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - Vector, - VectorType, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, + VectorValue, + kFloatScalarsAndVectors, + kConcreteIntegerScalarsAndVectors, + scalarTypeOf, + Type, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -28,7 +26,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord(kAllFloatScalarsAndVectors); +const kValuesTypes = objectsToRecord(kFloatScalarsAndVectors); g.test('values') .desc( @@ -56,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -64,7 +62,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const type = kValuesTypes[t.params.type]; const expectedResult = isRepresentable( Math.abs(Math.atan2(Number(t.params.x), Number(t.params.y))), - elementType(type) + scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -75,7 +73,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument_y') .desc( @@ -86,11 +84,11 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() .params(u => u.combine('type', keysOf(kIntegerArgumentTypes))) .fn(t => { const yTy = kIntegerArgumentTypes[t.params.type]; - const xTy = yTy instanceof Vector ? new VectorType(yTy.size, TypeF32) : TypeF32; + const xTy = yTy instanceof VectorValue ? Type.vec(yTy.size, Type.f32) : Type.f32; validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ yTy === TypeF32, + /* expectedResult */ yTy === Type.f32, [yTy.create(1), xTy.create(1)], 'constant' ); @@ -105,11 +103,11 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() .params(u => u.combine('type', keysOf(kIntegerArgumentTypes))) .fn(t => { const xTy = kIntegerArgumentTypes[t.params.type]; - const yTy = xTy instanceof Vector ? new VectorType(xTy.size, TypeF32) : TypeF32; + const yTy = xTy instanceof VectorValue ? Type.vec(xTy.size, Type.f32) : Type.f32; validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ xTy === TypeF32, + /* expectedResult */ xTy === Type.f32, [yTy.create(1), xTy.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/atanh.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/atanh.spec.ts index a299284c877b..1a9184a7416c 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/atanh.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/atanh.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { absBigInt } from '../../../../../util/math.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -27,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -52,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -70,7 +65,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -84,7 +79,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/ceil.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/ceil.spec.ts index d415c4b9dd3c..951958d02c12 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/ceil.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/ceil.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() never .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -59,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() never ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -73,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/clamp.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/clamp.spec.ts index b05bc030f437..9a23328d650f 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/clamp.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/clamp.spec.ts @@ -6,9 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - elementType, - kAllFloatAndConcreteIntegerScalarsAndVectors, + Type, + kFloatScalarsAndVectors, + kConcreteIntegerScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -21,7 +22,10 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord(kAllFloatAndConcreteIntegerScalarsAndVectors); +const kValuesTypes = objectsToRecord([ + ...kFloatScalarsAndVectors, + ...kConcreteIntegerScalarsAndVectors, +]); g.test('values') .desc( @@ -40,7 +44,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('high', u => fullRangeForType(kValuesTypes[u.type], 4)) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) diff --git a/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts b/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts index 62924453f13a..6c46bfb0a054 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/const_override_validation.ts @@ -2,11 +2,11 @@ import { assert, unreachable } from '../../../../../../common/util/util.js'; import { kValue } from '../../../../../util/constants.js'; import { Type, - TypeF16, Value, - elementType, - elementsOf, + elementTypeOf, isAbstractType, + scalarElementsOf, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { scalarF16Range, @@ -23,7 +23,7 @@ export function rangeForType( bigint_range: readonly bigint[] ): (type: Type) => readonly (number | bigint)[] { return (type: Type): readonly (number | bigint)[] => { - switch (elementType(type).kind) { + switch (scalarTypeOf(type).kind) { case 'abstract-float': case 'f32': case 'f16': @@ -132,7 +132,7 @@ export type ConstantOrOverrideStage = 'constant' | 'override'; * @returns true if evaluation stage `stage` supports expressions of type @p. */ export function stageSupportsType(stage: ConstantOrOverrideStage, type: Type) { - if (stage === 'override' && isAbstractType(elementType(type)!)) { + if (stage === 'override' && isAbstractType(elementTypeOf(type)!)) { // Abstract numerics are concretized before being used in an override expression. return false; } @@ -155,8 +155,8 @@ export function validateConstOrOverrideBuiltinEval( args: Value[], stage: ConstantOrOverrideStage ) { - const elTys = args.map(arg => elementType(arg.type)!); - const enables = elTys.some(ty => ty === TypeF16) ? 'enable f16;' : ''; + const elTys = args.map(arg => elementTypeOf(arg.type)!); + const enables = elTys.some(ty => ty === Type.f16) ? 'enable f16;' : ''; switch (stage) { case 'constant': { @@ -175,7 +175,7 @@ const v = ${builtin}(${args.map(arg => arg.wgsl()).join(', ')});` let numOverrides = 0; for (const arg of args) { const argOverrides: string[] = []; - for (const el of elementsOf(arg)) { + for (const el of scalarElementsOf(arg)) { const name = `o${numOverrides++}`; overrideDecls.push(`override ${name} : ${el.type};`); argOverrides.push(name); @@ -201,7 +201,7 @@ export function fullRangeForType(type: Type, count?: number): readonly (number | if (count === undefined) { count = 25; } - switch (elementType(type)?.kind) { + switch (scalarTypeOf(type)?.kind) { case 'abstract-float': return scalarF64Range({ pos_sub: Math.ceil((count * 1) / 5), diff --git a/src/webgpu/shader/validation/expression/call/builtin/cos.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/cos.spec.ts index b62c236803c0..81d283abb299 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/cos.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/cos.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +24,8 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); + g.test('values') .desc( ` @@ -50,7 +46,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -64,7 +60,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -78,7 +74,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/cosh.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/cosh.spec.ts index 55d0200ef16b..4178f5760d87 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/cosh.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/cosh.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +23,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -46,7 +40,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -55,7 +49,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.cosh(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -66,7 +60,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -80,7 +74,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/degrees.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/degrees.spec.ts index 4e4137daf4bd..f1cba6a6aef8 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/degrees.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/degrees.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +23,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -46,7 +40,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -55,7 +49,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input const expectedResult = isRepresentable( (Number(t.params.value) * 180) / Math.PI, // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -66,7 +60,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -80,7 +74,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/derivatives.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/derivatives.spec.ts index 474f14e03ee7..54620ce17904 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/derivatives.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/derivatives.spec.ts @@ -5,12 +5,10 @@ Validation tests for derivative builtins. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - TypeMat, - elementType, - kAllConcreteIntegerScalarsAndVectors, - kAllF16ScalarsAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConcreteF16ScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -98,10 +96,10 @@ fn foo() { // The list of invalid argument types to test, with an f32 control case. const kArgumentTypes = objectsToRecord([ - TypeF32, - ...kAllConcreteIntegerScalarsAndVectors, - ...kAllF16ScalarsAndVectors, - TypeMat(2, 2, TypeF32), + Type.f32, + ...kConcreteIntegerScalarsAndVectors, + ...kConcreteF16ScalarsAndVectors, + Type.mat2x2f, ]); g.test('invalid_argument_types') @@ -115,17 +113,17 @@ Derivative builtins only accept f32 scalar and vector types. u.combine('type', keysOf(kArgumentTypes)).combine('call', ['', ...kDerivativeBuiltins]) ) .beforeAllSubcases(t => { - if (elementType(kArgumentTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kArgumentTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) .fn(t => { const type = kArgumentTypes[t.params.type]; const code = ` -${elementType(kArgumentTypes[t.params.type]) === TypeF16 ? 'enable f16;' : ''} +${scalarTypeOf(kArgumentTypes[t.params.type]) === Type.f16 ? 'enable f16;' : ''} fn foo() { let x: ${type.toString()} = ${t.params.call}(${type.create(1).wgsl()}); }`; - t.expectCompileResult(kArgumentTypes[t.params.type] === TypeF32 || t.params.call === '', code); + t.expectCompileResult(kArgumentTypes[t.params.type] === Type.f32 || t.params.call === '', code); }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/exp.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/exp.spec.ts index a7a37fb08cdb..dcbd5b79e51d 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/exp.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/exp.spec.ts @@ -7,13 +7,10 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { kValue } from '../../../../../util/constants.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - TypeAbstractFloat, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -27,10 +24,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); const valueForType = rangeForType( [ @@ -76,7 +70,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('value', u => valueForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -85,7 +79,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.exp(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -96,7 +90,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -110,7 +104,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/exp2.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/exp2.spec.ts index 40a8542b8d95..0144abeefb04 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/exp2.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/exp2.spec.ts @@ -7,13 +7,10 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { kValue } from '../../../../../util/constants.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - TypeAbstractFloat, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -27,10 +24,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); const valueForType = rangeForType( [ @@ -76,7 +70,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('value', u => valueForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -85,7 +79,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.pow(2, Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -96,7 +90,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -110,7 +104,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/floor.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/floor.spec.ts index 6a12c3d67db8..b65fafc74466 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/floor.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/floor.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,8 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); + g.test('values') .desc( ` @@ -43,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() never .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -58,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() never ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -72,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/inverseSqrt.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/inverseSqrt.spec.ts index f459303d580b..6310bfe25fee 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/inverseSqrt.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/inverseSqrt.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - TypeAbstractFloat, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -28,10 +25,8 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); + g.test('values') .desc( ` @@ -52,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -63,7 +58,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input isRepresentable( 1 / Math.sqrt(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -74,7 +69,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -88,7 +83,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/length.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/length.spec.ts index 1f24a86d9107..003ad6811d72 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/length.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/length.spec.ts @@ -7,19 +7,13 @@ import { makeTestGroup } from '../../../../../../common/framework/test_group.js' import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { ScalarType, - TypeF16, - TypeF32, - elementType, - kAllFloatScalars, - kAllFloatVector2, - kAllFloatVector3, - kAllFloatVector4, - kAllConcreteIntegerScalarsAndVectors, - kAbstractIntegerScalar, - kAbstractIntegerVector2, - TypeAbstractFloat, - kAbstractIntegerVector3, - kAbstractIntegerVector4, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalar, + kConvertableToFloatVec2, + kConvertableToFloatVec3, + kConvertableToFloatVec4, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -61,18 +55,18 @@ function calculate( isIntermediateRepresentable: isRepresentable( squareSum, // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ), isResultRepresentable: isRepresentable( result, // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ), result, }; } -const kScalarTypes = objectsToRecord([...kAbstractIntegerScalar, ...kAllFloatScalars]); +const kScalarTypes = objectsToRecord(kConvertableToFloatScalar); g.test('scalar') .desc( @@ -90,7 +84,7 @@ the input scalar value always compiles without error .expand('value', u => fullRangeForType(kScalarTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kScalarTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kScalarTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -106,7 +100,7 @@ the input scalar value always compiles without error ); }); -const kVec2Types = objectsToRecord([...kAbstractIntegerVector2, ...kAllFloatVector2]); +const kVec2Types = objectsToRecord(kConvertableToFloatVec2); g.test('vec2') .desc( @@ -122,11 +116,11 @@ Validates that constant evaluation and override evaluation of ${builtin}() with .beginSubcases() .expand('x', u => fullRangeForType(kVec2Types[u.type], 5)) .expand('y', u => fullRangeForType(kVec2Types[u.type], 5)) - .expand('_result', u => [calculate([u.x, u.y], elementType(kVec2Types[u.type]))]) + .expand('_result', u => [calculate([u.x, u.y], scalarTypeOf(kVec2Types[u.type]))]) .filter(u => u._result.isResultRepresentable === u._result.isIntermediateRepresentable) ) .beforeAllSubcases(t => { - if (elementType(kVec2Types[t.params.type]) === TypeF16) { + if (scalarTypeOf(kVec2Types[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -141,7 +135,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() with ); }); -const kVec3Types = objectsToRecord([...kAbstractIntegerVector3, ...kAllFloatVector3]); +const kVec3Types = objectsToRecord(kConvertableToFloatVec3); g.test('vec3') .desc( @@ -158,11 +152,11 @@ Validates that constant evaluation and override evaluation of ${builtin}() with .expand('x', u => fullRangeForType(kVec3Types[u.type], 4)) .expand('y', u => fullRangeForType(kVec3Types[u.type], 4)) .expand('z', u => fullRangeForType(kVec3Types[u.type], 4)) - .expand('_result', u => [calculate([u.x, u.y, u.z], elementType(kVec3Types[u.type]))]) + .expand('_result', u => [calculate([u.x, u.y, u.z], scalarTypeOf(kVec3Types[u.type]))]) .filter(u => u._result.isResultRepresentable === u._result.isIntermediateRepresentable) ) .beforeAllSubcases(t => { - if (elementType(kVec3Types[t.params.type]) === TypeF16) { + if (scalarTypeOf(kVec3Types[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -177,7 +171,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() with ); }); -const kVec4Types = objectsToRecord([...kAbstractIntegerVector4, ...kAllFloatVector4]); +const kVec4Types = objectsToRecord(kConvertableToFloatVec4); g.test('vec4') .desc( @@ -195,11 +189,11 @@ Validates that constant evaluation and override evaluation of ${builtin}() with .expand('y', u => fullRangeForType(kVec4Types[u.type], 3)) .expand('z', u => fullRangeForType(kVec4Types[u.type], 3)) .expand('w', u => fullRangeForType(kVec4Types[u.type], 3)) - .expand('_result', u => [calculate([u.x, u.y, u.z, u.w], elementType(kVec4Types[u.type]))]) + .expand('_result', u => [calculate([u.x, u.y, u.z, u.w], scalarTypeOf(kVec4Types[u.type]))]) .filter(u => u._result.isResultRepresentable === u._result.isIntermediateRepresentable) ) .beforeAllSubcases(t => { - if (elementType(kVec4Types[t.params.type]) === TypeF16) { + if (scalarTypeOf(kVec4Types[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -214,7 +208,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() with ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -228,7 +222,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/log.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/log.spec.ts index bffc433103e8..6d755304f2ff 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/log.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/log.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -59,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -73,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/log2.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/log2.spec.ts index 6eaf08993c8c..0dfe64153651 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/log2.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/log2.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,8 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); + g.test('values') .desc( ` @@ -43,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -58,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -72,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/modf.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/modf.spec.ts index bdb0691436f4..2a90fa878ea6 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/modf.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/modf.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -59,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -73,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/radians.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/radians.spec.ts index 8cb7f62d92b9..8689bc3dbbe8 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/radians.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/radians.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -59,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -73,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/round.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/round.spec.ts index 267c743c805f..dae7482c18ce 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/round.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/round.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { fpTraitsFor } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +24,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,10 +39,10 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) .beginSubcases() .expand('value', u => { - if (elementType(kValuesTypes[u.type]).kind === 'abstract-int') { + if (scalarTypeOf(kValuesTypes[u.type]).kind === 'abstract-int') { return fullRangeForType(kValuesTypes[u.type]); } else { - const constants = fpTraitsFor(elementType(kValuesTypes[u.type])).constants(); + const constants = fpTraitsFor(scalarTypeOf(kValuesTypes[u.type])).constants(); return unique(fullRangeForType(kValuesTypes[u.type]), [ constants.negative.min + 0.1, constants.positive.max - 0.1, @@ -56,7 +51,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input }) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -71,7 +66,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -85,7 +80,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/saturate.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/saturate.spec.ts index c7b0a50e9409..cbd1b3f369ff 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/saturate.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/saturate.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -24,10 +22,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -44,7 +39,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -59,7 +54,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -73,7 +68,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/sign.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/sign.spec.ts index f844961aee27..f8e00ab9486d 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/sign.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/sign.spec.ts @@ -6,11 +6,11 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatAndSignedIntegerScalarsAndVectors, - kAllUnsignedIntegerScalarsAndVectors, + Type, + kFloatScalarsAndVectors, + kConcreteSignedIntegerScalarsAndVectors, + kConcreteUnsignedIntegerScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -23,7 +23,10 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord(kAllFloatAndSignedIntegerScalarsAndVectors); +const kValuesTypes = objectsToRecord([ + ...kFloatScalarsAndVectors, + ...kConcreteSignedIntegerScalarsAndVectors, +]); g.test('values') .desc( @@ -40,7 +43,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -56,8 +59,8 @@ Validates that constant evaluation and override evaluation of ${builtin}() input }); const kUnsignedIntegerArgumentTypes = objectsToRecord([ - TypeF32, - ...kAllUnsignedIntegerScalarsAndVectors, + Type.f32, + ...kConcreteUnsignedIntegerScalarsAndVectors, ]); g.test('unsigned_integer_argument') @@ -72,7 +75,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/sin.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/sin.spec.ts index 9e0d091e11d0..3c807d094c5c 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/sin.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/sin.spec.ts @@ -6,12 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +24,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -51,7 +46,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -65,7 +60,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -79,7 +74,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/sinh.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/sinh.spec.ts index d4c94e1a5290..1983d0e1a7e4 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/sinh.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/sinh.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -26,10 +23,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -46,7 +40,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec .expand('value', u => fullRangeForType(kValuesTypes[u.type])) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -55,7 +49,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const expectedResult = isRepresentable( Math.sinh(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -66,7 +60,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -80,7 +74,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/sqrt.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/sqrt.spec.ts index 0844652acdf6..7e983adf188c 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/sqrt.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/sqrt.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { isRepresentable } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -28,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -53,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -64,7 +58,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input isRepresentable( Math.sqrt(Number(t.params.value)), // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); validateConstOrOverrideBuiltinEval( t, @@ -75,7 +69,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() input ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -89,7 +83,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(1)], 'constant' ); diff --git a/src/webgpu/shader/validation/expression/call/builtin/tan.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/tan.spec.ts index 02616455a67e..097c2b374d95 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/tan.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/tan.spec.ts @@ -6,13 +6,10 @@ Validation tests for the ${builtin}() builtin. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; import { - TypeF16, - TypeF32, - elementType, - kAllFloatScalarsAndVectors, - kAllConcreteIntegerScalarsAndVectors, - kAllAbstractIntegerScalarAndVectors, - TypeAbstractFloat, + Type, + kConcreteIntegerScalarsAndVectors, + kConvertableToFloatScalarsAndVectors, + scalarTypeOf, } from '../../../../../util/conversion.js'; import { fpTraitsFor } from '../../../../../util/floating_point.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -28,10 +25,7 @@ import { export const g = makeTestGroup(ShaderValidationTest); -const kValuesTypes = objectsToRecord([ - ...kAllAbstractIntegerScalarAndVectors, - ...kAllFloatScalarsAndVectors, -]); +const kValuesTypes = objectsToRecord(kConvertableToFloatScalarsAndVectors); g.test('values') .desc( @@ -53,7 +47,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ) ) .beforeAllSubcases(t => { - if (elementType(kValuesTypes[t.params.type]) === TypeF16) { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { t.selectDeviceOrSkipTestCase('shader-f16'); } }) @@ -61,7 +55,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec const type = kValuesTypes[t.params.type]; const fp = fpTraitsFor( // AbstractInt is converted to AbstractFloat before calling into the builtin - elementType(type).kind === 'abstract-int' ? TypeAbstractFloat : elementType(type) + scalarTypeOf(type).kind === 'abstract-int' ? Type.abstractFloat : scalarTypeOf(type) ); const smallestPositive = fp.constants().positive.min; const v = fp.quantize(Number(t.params.value)); @@ -75,7 +69,7 @@ Validates that constant evaluation and override evaluation of ${builtin}() rejec ); }); -const kIntegerArgumentTypes = objectsToRecord([TypeF32, ...kAllConcreteIntegerScalarsAndVectors]); +const kIntegerArgumentTypes = objectsToRecord([Type.f32, ...kConcreteIntegerScalarsAndVectors]); g.test('integer_argument') .desc( @@ -89,7 +83,7 @@ Validates that scalar and vector integer arguments are rejected by ${builtin}() validateConstOrOverrideBuiltinEval( t, builtin, - /* expectedResult */ type === TypeF32, + /* expectedResult */ type === Type.f32, [type.create(0)], 'constant' ); diff --git a/src/webgpu/shader/validation/extension/readonly_and_readwrite_storage_textures.spec.ts b/src/webgpu/shader/validation/extension/readonly_and_readwrite_storage_textures.spec.ts new file mode 100644 index 000000000000..c74694d4b551 --- /dev/null +++ b/src/webgpu/shader/validation/extension/readonly_and_readwrite_storage_textures.spec.ts @@ -0,0 +1,48 @@ +export const description = ` +Validation tests for the readonly_and_readwrite_storage_textures language feature +`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { TexelFormats } from '../../types.js'; +import { ShaderValidationTest } from '../shader_validation_test.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kFeatureName = 'readonly_and_readwrite_storage_textures'; + +g.test('var_decl') + .desc( + `Checks that the read and read_write access modes are only allowed with the language feature present` + ) + .paramsSubcasesOnly(u => + u + .combine('type', [ + 'texture_storage_1d', + 'texture_storage_2d', + 'texture_storage_2d_array', + 'texture_storage_3d', + ]) + .combine('format', TexelFormats) + .combine('access', ['read', 'write', 'read_write']) + ) + .fn(t => { + const { type, format, access } = t.params; + const source = `@group(0) @binding(0) var t : ${type}<${format.format}, ${access}>;`; + const requiresFeature = access !== 'write'; + t.expectCompileResult(t.hasLanguageFeature(kFeatureName) || !requiresFeature, source); + }); + +g.test('textureBarrier') + .desc( + `Checks that the textureBarrier() builtin is only allowed with the language feature present` + ) + .fn(t => { + t.expectCompileResult( + t.hasLanguageFeature(kFeatureName), + ` + @workgroup_size(1) @compute fn main() { + textureBarrier(); + } + ` + ); + }); diff --git a/src/webgpu/shader/validation/parse/diagnostic.spec.ts b/src/webgpu/shader/validation/parse/diagnostic.spec.ts index 757cf50cbba4..701ae46f3a0d 100644 --- a/src/webgpu/shader/validation/parse/diagnostic.spec.ts +++ b/src/webgpu/shader/validation/parse/diagnostic.spec.ts @@ -220,3 +220,242 @@ g.test('after_other_directives') code += generateDiagnostic('directive', 'info', 'derivative_uniformity') + ';'; t.expectCompileResult(true, code); }); + +interface ScopeCase { + code: string; + result: boolean | 'warn'; +} + +function scopeCode(body: string): string { + return ` +@group(0) @binding(0) var t : texture_1d; +@group(0) @binding(1) var s : sampler; +var non_uniform_cond : bool; +var non_uniform_coord : f32; +var non_uniform_val : u32; +@fragment fn main() { + ${body} +} +`; +} + +const kScopeCases: Record = { + override_global_off: { + code: ` + ${generateDiagnostic('directive', 'error', 'derivative_uniformity')}; + ${scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + }`)}; + `, + result: true, + }, + override_global_on: { + code: ` + ${generateDiagnostic('directive', 'off', 'derivative_uniformity')}; + ${scopeCode(` + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + }`)} + `, + result: false, + }, + override_global_warn: { + code: ` + ${generateDiagnostic('directive', 'error', 'derivative_uniformity')}; + ${scopeCode(` + ${generateDiagnostic('', 'warning', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + }`)} + `, + result: 'warn', + }, + global_if_nothing_else_warn: { + code: ` + ${generateDiagnostic('directive', 'warning', 'derivative_uniformity')}; + ${scopeCode(` + if non_uniform_cond { + _ = textureSample(t,s,0.0); + }`)} + `, + result: 'warn', + }, + deepest_nesting_warn: { + code: scopeCode(` + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if non_uniform_cond { + ${generateDiagnostic('', 'warning', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + } + }`), + result: 'warn', + }, + deepest_nesting_off: { + code: scopeCode(` + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if non_uniform_cond { + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + } + }`), + result: true, + }, + deepest_nesting_error: { + code: scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + } + }`), + result: false, + }, + other_nest_unaffected: { + code: ` + ${generateDiagnostic('directive', 'warning', 'derivative_uniformity')}; + ${scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + _ = textureSample(t,s,0.0); + } + if non_uniform_cond { + _ = textureSample(t,s,0.0); + }`)} + `, + result: 'warn', + }, + deeper_nest_no_effect: { + code: ` + ${generateDiagnostic('directive', 'error', 'derivative_uniformity')}; + ${scopeCode(` + if non_uniform_cond { + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + } + _ = textureSample(t,s,0.0); + }`)} + `, + result: false, + }, + call_unaffected_error: { + code: ` + ${generateDiagnostic('directive', 'error', 'derivative_uniformity')}; + fn foo() { _ = textureSample(t,s,0.0); } + ${scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + foo(); + }`)} + `, + result: false, + }, + call_unaffected_warn: { + code: ` + ${generateDiagnostic('directive', 'warning', 'derivative_uniformity')}; + fn foo() { _ = textureSample(t,s,0.0); } + ${scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if non_uniform_cond { + foo(); + }`)} + `, + result: 'warn', + }, + call_unaffected_off: { + code: ` + ${generateDiagnostic('directive', 'off', 'derivative_uniformity')}; + fn foo() { _ = textureSample(t,s,0.0); } + ${scopeCode(` + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if non_uniform_cond { + foo(); + }`)} + `, + result: true, + }, + if_condition_error: { + code: scopeCode(` + if (non_uniform_cond) { + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + if textureSample(t,s,non_uniform_coord).x > 0.0 + ${generateDiagnostic('', 'off', 'derivative_uniformity')} { + } + }`), + result: false, + }, + if_condition_warn: { + code: scopeCode(` + if non_uniform_cond { + ${generateDiagnostic('', 'warning', 'derivative_uniformity')} + if textureSample(t,s,non_uniform_coord).x > 0.0 + ${generateDiagnostic('', 'error', 'derivative_uniformity')} { + } + }`), + result: 'warn', + }, + if_condition_off: { + code: scopeCode(` + if non_uniform_cond { + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + if textureSample(t,s,non_uniform_coord).x > 0.0 + ${generateDiagnostic('', 'error', 'derivative_uniformity')} { + } + }`), + result: true, + }, + switch_error: { + code: scopeCode(` + ${generateDiagnostic('', 'error', 'derivative_uniformity')} + switch non_uniform_val { + case 0 ${generateDiagnostic('', 'off', 'derivative_uniformity')} { + } + default { + _ = textureSample(t,s,0.0); + } + }`), + result: false, + }, + switch_warn: { + code: scopeCode(` + ${generateDiagnostic('', 'warning', 'derivative_uniformity')} + switch non_uniform_val { + case 0 ${generateDiagnostic('', 'off', 'derivative_uniformity')} { + } + default { + _ = textureSample(t,s,0.0); + } + }`), + result: 'warn', + }, + switch_off: { + code: scopeCode(` + ${generateDiagnostic('', 'off', 'derivative_uniformity')} + switch non_uniform_val { + case 0 ${generateDiagnostic('', 'error', 'derivative_uniformity')}{ + } + default { + _ = textureSample(t,s,0.0); + } + }`), + result: true, + }, +}; + +g.test('diagnostic_scoping') + .specURL('https://gpuweb.github.io/gpuweb/wgsl/#diagnostics') + .desc('Tests that innermost scope controls the diagnostic') + .params(u => u.combine('case', keysOf(kScopeCases))) + .fn(t => { + const testcase = kScopeCases[t.params.case]; + if (testcase.result === 'warn') { + t.expectCompileWarning(true, testcase.code); + } else { + t.expectCompileResult(testcase.result as boolean, testcase.code); + } + }); diff --git a/src/webgpu/util/compare.ts b/src/webgpu/util/compare.ts index 95573e6ceae2..7cb71ca8de5a 100644 --- a/src/webgpu/util/compare.ts +++ b/src/webgpu/util/compare.ts @@ -8,7 +8,14 @@ import { import { Expectation, toComparator } from '../shader/execution/expression/expectation.js'; import BinaryStream from './binary_stream.js'; -import { isFloatValue, Matrix, Scalar, Value, Vector } from './conversion.js'; +import { + isFloatValue, + isScalarValue, + MatrixValue, + ScalarValue, + Value, + VectorValue, +} from './conversion.js'; import { FPInterval } from './floating_point.js'; /** Comparison describes the result of a Comparator function. */ @@ -98,9 +105,9 @@ function compareValue(got: Value, expected: Value): Comparison { } } - if (got instanceof Scalar) { + if (isScalarValue(got)) { const g = got; - const e = expected as Scalar; + const e = expected as ScalarValue; const isFloat = g.type.kind === 'f64' || g.type.kind === 'f32' || g.type.kind === 'f16'; const matched = (isFloat && (g.value as number) === (e.value as number)) || (!isFloat && g.value === e.value); @@ -111,8 +118,8 @@ function compareValue(got: Value, expected: Value): Comparison { }; } - if (got instanceof Vector) { - const e = expected as Vector; + if (got instanceof VectorValue) { + const e = expected as VectorValue; const gLen = got.elements.length; const eLen = e.elements.length; let matched = gLen === eLen; @@ -130,8 +137,8 @@ function compareValue(got: Value, expected: Value): Comparison { }; } - if (got instanceof Matrix) { - const e = expected as Matrix; + if (got instanceof MatrixValue) { + const e = expected as MatrixValue; const gCols = got.type.cols; const eCols = e.type.cols; const gRows = got.type.rows; @@ -175,7 +182,7 @@ function compareInterval(got: Value, expected: FPInterval): Comparison { } } - if (got instanceof Scalar) { + if (isScalarValue(got)) { const g = got.value as number; const matched = expected.contains(g); return { @@ -197,7 +204,7 @@ function compareInterval(got: Value, expected: FPInterval): Comparison { */ function compareVector(got: Value, expected: FPInterval[]): Comparison { // Check got type - if (!(got instanceof Vector)) { + if (!(got instanceof VectorValue)) { return { matched: false, got: `${Colors.red((typeof got).toString())}(${got})`, @@ -262,7 +269,7 @@ function convertArrayToString(m: T[]): string { */ function compareMatrix(got: Value, expected: FPInterval[][]): Comparison { // Check got type - if (!(got instanceof Matrix)) { + if (!(got instanceof MatrixValue)) { return { matched: false, got: `${Colors.red((typeof got).toString())}(${got})`, diff --git a/src/webgpu/util/conversion.ts b/src/webgpu/util/conversion.ts index ac6ff5bbea38..a44f34cedfeb 100644 --- a/src/webgpu/util/conversion.ts +++ b/src/webgpu/util/conversion.ts @@ -596,9 +596,13 @@ export type ScalarKind = export class ScalarType { readonly kind: ScalarKind; // The named type readonly _size: number; // In bytes - readonly read: (buf: Uint8Array, offset: number) => Scalar; // reads a scalar from a buffer + readonly read: (buf: Uint8Array, offset: number) => ScalarValue; // reads a scalar from a buffer - constructor(kind: ScalarKind, size: number, read: (buf: Uint8Array, offset: number) => Scalar) { + constructor( + kind: ScalarKind, + size: number, + read: (buf: Uint8Array, offset: number) => ScalarValue + ) { this.kind = kind; this._size = size; this.read = read; @@ -612,8 +616,12 @@ export class ScalarType { return this._size; } - /** Constructs a Scalar of this type with `value` */ - public create(value: number | bigint): Scalar { + public get alignment(): number { + return this._size; + } + + /** Constructs a ScalarValue of this type with `value` */ + public create(value: number | bigint): ScalarValue { switch (typeof value) { case 'number': switch (this.kind) { @@ -659,6 +667,20 @@ export class VectorType { readonly width: number; // Number of elements in the vector readonly elementType: ScalarType; // Element type + // Maps a string representation of a vector type to vector type. + private static instances = new Map(); + + static create(width: number, elementType: ScalarType): VectorType { + const key = `${elementType.toString()} ${width}}`; + let ty = this.instances.get(key); + if (ty !== undefined) { + return ty; + } + ty = new VectorType(width, elementType); + this.instances.set(key, ty); + return ty; + } + constructor(width: number, elementType: ScalarType) { this.width = width; this.elementType = elementType; @@ -668,13 +690,13 @@ export class VectorType { * @returns a vector constructed from the values read from the buffer at the * given byte offset */ - public read(buf: Uint8Array, offset: number): Vector { - const elements: Array = []; + public read(buf: Uint8Array, offset: number): VectorValue { + const elements: Array = []; for (let i = 0; i < this.width; i++) { elements[i] = this.elementType.read(buf, offset); offset += this.elementType.size; } - return new Vector(elements); + return new VectorValue(elements); } public toString(): string { @@ -685,37 +707,45 @@ export class VectorType { return this.elementType.size * this.width; } + public get alignment(): number { + return VectorType.alignmentOf(this.width, this.elementType); + } + + public static alignmentOf(width: number, elementType: ScalarType) { + return elementType.size * (width === 3 ? 4 : width); + } + /** Constructs a Vector of this type with the given values */ - public create(value: (number | bigint) | readonly (number | bigint)[]): Vector { + public create(value: (number | bigint) | readonly (number | bigint)[]): VectorValue { if (value instanceof Array) { assert(value.length === this.width); } else { value = Array(this.width).fill(value); } - return new Vector(value.map(v => this.elementType.create(v))); + return new VectorValue(value.map(v => this.elementType.create(v))); } } -// Maps a string representation of a vector type to vector type. -const vectorTypes = new Map(); - -export function TypeVec(width: number, elementType: ScalarType): VectorType { - const key = `${elementType.toString()} ${width}}`; - let ty = vectorTypes.get(key); - if (ty !== undefined) { - return ty; - } - ty = new VectorType(width, elementType); - vectorTypes.set(key, ty); - return ty; -} - /** MatrixType describes the type of WGSL Matrix. */ export class MatrixType { readonly cols: number; // Number of columns in the Matrix readonly rows: number; // Number of elements per column in the Matrix readonly elementType: ScalarType; // Element type + // Maps a string representation of a Matrix type to Matrix type. + private static instances = new Map(); + + static create(cols: number, rows: number, elementType: ScalarType): MatrixType { + const key = `${elementType.toString()} ${cols} ${rows}`; + let ty = this.instances.get(key); + if (ty !== undefined) { + return ty; + } + ty = new MatrixType(cols, rows, elementType); + this.instances.set(key, ty); + return ty; + } + constructor(cols: number, rows: number, elementType: ScalarType) { this.cols = cols; this.rows = rows; @@ -732,8 +762,8 @@ export class MatrixType { * @returns a Matrix constructed from the values read from the buffer at the * given byte offset */ - public read(buf: Uint8Array, offset: number): Matrix { - const elements: Scalar[][] = [...Array(this.cols)].map(_ => [...Array(this.rows)]); + public read(buf: Uint8Array, offset: number): MatrixValue { + const elements: ScalarValue[][] = [...Array(this.cols)].map(_ => [...Array(this.rows)]); for (let c = 0; c < this.cols; c++) { for (let r = 0; r < this.rows; r++) { elements[c][r] = this.elementType.read(buf, offset); @@ -745,15 +775,23 @@ export class MatrixType { offset += this.elementType.size; } } - return new Matrix(elements); + return new MatrixValue(elements); } public toString(): string { return `mat${this.cols}x${this.rows}<${this.elementType}>`; } + public get size(): number { + return VectorType.alignmentOf(this.rows, this.elementType) * this.cols; + } + + public get alignment(): number { + return VectorType.alignmentOf(this.rows, this.elementType); + } + /** Constructs a Matrix of this type with the given values */ - public create(value: (number | bigint) | readonly (number | bigint)[]): Matrix { + public create(value: (number | bigint) | readonly (number | bigint)[]): MatrixValue { if (value instanceof Array) { assert(value.length === this.cols * this.rows); } else { @@ -764,26 +802,59 @@ export class MatrixType { const start = i * this.rows; columns.push(value.slice(start, start + this.rows)); } - return new Matrix(columns.map(c => c.map(v => this.elementType.create(v)))); + return new MatrixValue(columns.map(c => c.map(v => this.elementType.create(v)))); } } -// Maps a string representation of a Matrix type to Matrix type. -const matrixTypes = new Map(); +/** ArrayType describes the type of WGSL Array. */ +export class ArrayType { + readonly count: number; // Number of elements in the array + readonly elementType: Type; // Element type + + // Maps a string representation of a array type to array type. + private static instances = new Map(); -export function TypeMat(cols: number, rows: number, elementType: ScalarType): MatrixType { - const key = `${elementType.toString()} ${cols} ${rows}`; - let ty = matrixTypes.get(key); - if (ty !== undefined) { + static create(count: number, elementType: Type): ArrayType { + const key = `${elementType.toString()} ${count}`; + let ty = this.instances.get(key); + if (ty !== undefined) { + return ty; + } + ty = new ArrayType(count, elementType); + this.instances.set(key, ty); return ty; } - ty = new MatrixType(cols, rows, elementType); - matrixTypes.set(key, ty); - return ty; -} -/** Type is a ScalarType, VectorType, or MatrixType. */ -export type Type = ScalarType | VectorType | MatrixType; + constructor(count: number, elementType: Type) { + this.count = count; + this.elementType = elementType; + } + + /** + * @returns a array constructed from the values read from the buffer at the + * given byte offset + */ + public read(buf: Uint8Array, offset: number): ArrayValue { + const elements: Array = []; + for (let i = 0; i < this.count; i++) { + elements[i] = this.elementType.read(buf, offset); + offset += this.elementType.size; + } + return new ArrayValue(elements); + } + + public toString(): string { + return `array<${this.elementType}, ${this.count}>`; + } + + public get size(): number { + return this.elementType.alignment * this.count; + } + + public get alignment(): number { + return this.elementType.alignment; + } +} /** ArrayElementType infers the element type of the indexable type A */ type ArrayElementType = A extends { [index: number]: infer T } ? T : never; @@ -800,74 +871,130 @@ function valueFromBytes( return workingDataOut[0] as ArrayElementType; } -export const TypeAbstractInt = new ScalarType( - 'abstract-int', - 8, - (buf: Uint8Array, offset: number) => abstractInt(valueFromBytes(workingDataI64, buf, offset)) +const abstractIntType = new ScalarType('abstract-int', 8, (buf: Uint8Array, offset: number) => + abstractInt(valueFromBytes(workingDataI64, buf, offset)) ); -export const TypeI32 = new ScalarType('i32', 4, (buf: Uint8Array, offset: number) => +const i32Type = new ScalarType('i32', 4, (buf: Uint8Array, offset: number) => i32(valueFromBytes(workingDataI32, buf, offset)) ); -export const TypeU32 = new ScalarType('u32', 4, (buf: Uint8Array, offset: number) => +const u32Type = new ScalarType('u32', 4, (buf: Uint8Array, offset: number) => u32(valueFromBytes(workingDataU32, buf, offset)) ); -export const TypeAbstractFloat = new ScalarType( - 'abstract-float', - 8, - (buf: Uint8Array, offset: number) => abstractFloat(valueFromBytes(workingDataF64, buf, offset)) -); -export const TypeF64 = new ScalarType('f64', 8, (buf: Uint8Array, offset: number) => - f64(valueFromBytes(workingDataF64, buf, offset)) -); -export const TypeF32 = new ScalarType('f32', 4, (buf: Uint8Array, offset: number) => - f32(valueFromBytes(workingDataF32, buf, offset)) -); -export const TypeI16 = new ScalarType('i16', 2, (buf: Uint8Array, offset: number) => +const i16Type = new ScalarType('i16', 2, (buf: Uint8Array, offset: number) => i16(valueFromBytes(workingDataI16, buf, offset)) ); -export const TypeU16 = new ScalarType('u16', 2, (buf: Uint8Array, offset: number) => +const u16Type = new ScalarType('u16', 2, (buf: Uint8Array, offset: number) => u16(valueFromBytes(workingDataU16, buf, offset)) ); -export const TypeF16 = new ScalarType('f16', 2, (buf: Uint8Array, offset: number) => - f16Bits(valueFromBytes(workingDataU16, buf, offset)) -); -export const TypeI8 = new ScalarType('i8', 1, (buf: Uint8Array, offset: number) => +const i8Type = new ScalarType('i8', 1, (buf: Uint8Array, offset: number) => i8(valueFromBytes(workingDataI8, buf, offset)) ); -export const TypeU8 = new ScalarType('u8', 1, (buf: Uint8Array, offset: number) => +const u8Type = new ScalarType('u8', 1, (buf: Uint8Array, offset: number) => u8(valueFromBytes(workingDataU8, buf, offset)) ); -export const TypeBool = new ScalarType('bool', 4, (buf: Uint8Array, offset: number) => +const abstractFloatType = new ScalarType('abstract-float', 8, (buf: Uint8Array, offset: number) => + abstractFloat(valueFromBytes(workingDataF64, buf, offset)) +); +const f64Type = new ScalarType('f64', 8, (buf: Uint8Array, offset: number) => + f64(valueFromBytes(workingDataF64, buf, offset)) +); +const f32Type = new ScalarType('f32', 4, (buf: Uint8Array, offset: number) => + f32(valueFromBytes(workingDataF32, buf, offset)) +); +const f16Type = new ScalarType('f16', 2, (buf: Uint8Array, offset: number) => + f16Bits(valueFromBytes(workingDataU16, buf, offset)) +); +const boolType = new ScalarType('bool', 4, (buf: Uint8Array, offset: number) => bool(valueFromBytes(workingDataU32, buf, offset) !== 0) ); +/** Type is a ScalarType, VectorType, MatrixType or ArrayType. */ +export type Type = ScalarType | VectorType | MatrixType | ArrayType; + +/** Type holds pre-declared Types along with helper constructor functions. */ +export const Type = { + abstractInt: abstractIntType, + i32: i32Type, + u32: u32Type, + i16: i16Type, + u16: u16Type, + i8: i8Type, + u8: u8Type, + + abstractFloat: abstractFloatType, + f64: f64Type, + f32: f32Type, + f16: f16Type, + + bool: boolType, + + vec: (width: number, elementType: ScalarType) => VectorType.create(width, elementType), + + vec2i: VectorType.create(2, i32Type), + vec2u: VectorType.create(2, u32Type), + vec2f: VectorType.create(2, f32Type), + vec2h: VectorType.create(2, f16Type), + vec3i: VectorType.create(3, i32Type), + vec3u: VectorType.create(3, u32Type), + vec3f: VectorType.create(3, f32Type), + vec3h: VectorType.create(3, f16Type), + vec4i: VectorType.create(4, i32Type), + vec4u: VectorType.create(4, u32Type), + vec4f: VectorType.create(4, f32Type), + vec4h: VectorType.create(4, f16Type), + + mat: (cols: number, rows: number, elementType: ScalarType) => + MatrixType.create(cols, rows, elementType), + + mat2x2f: MatrixType.create(2, 2, f32Type), + mat2x2h: MatrixType.create(2, 2, f16Type), + mat3x2f: MatrixType.create(3, 2, f32Type), + mat3x2h: MatrixType.create(3, 2, f16Type), + mat4x2f: MatrixType.create(4, 2, f32Type), + mat4x2h: MatrixType.create(4, 2, f16Type), + mat2x3f: MatrixType.create(2, 3, f32Type), + mat2x3h: MatrixType.create(2, 3, f16Type), + mat3x3f: MatrixType.create(3, 3, f32Type), + mat3x3h: MatrixType.create(3, 3, f16Type), + mat4x3f: MatrixType.create(4, 3, f32Type), + mat4x3h: MatrixType.create(4, 3, f16Type), + mat2x4f: MatrixType.create(2, 4, f32Type), + mat2x4h: MatrixType.create(2, 4, f16Type), + mat3x4f: MatrixType.create(3, 4, f32Type), + mat3x4h: MatrixType.create(3, 4, f16Type), + mat4x4f: MatrixType.create(4, 4, f32Type), + mat4x4h: MatrixType.create(4, 4, f16Type), + + array: (count: number, elementType: Type) => ArrayType.create(count, elementType), +}; + /** @returns the ScalarType from the ScalarKind */ export function scalarType(kind: ScalarKind): ScalarType { switch (kind) { case 'abstract-float': - return TypeAbstractFloat; + return Type.abstractFloat; case 'f64': - return TypeF64; + return Type.f64; case 'f32': - return TypeF32; + return Type.f32; case 'f16': - return TypeF16; + return Type.f16; case 'u32': - return TypeU32; + return Type.u32; case 'u16': - return TypeU16; + return Type.u16; case 'u8': - return TypeU8; + return Type.u8; case 'abstract-int': - return TypeAbstractInt; + return Type.abstractInt; case 'i32': - return TypeI32; + return Type.i32; case 'i16': - return TypeI16; + return Type.i16; case 'i8': - return TypeI8; + return Type.i8; case 'bool': - return TypeBool; + return Type.bool; } } @@ -882,23 +1009,54 @@ export function numElementsOf(ty: Type): number { if (ty instanceof MatrixType) { return ty.cols * ty.rows; } + if (ty instanceof ArrayType) { + return ty.count; + } throw new Error(`unhandled type ${ty}`); } /** @returns the scalar elements of the given Value */ -export function elementsOf(value: Value): Scalar[] { - if (value instanceof Scalar) { +export function elementsOf(value: Value): Value[] { + if (isScalarValue(value)) { return [value]; } - if (value instanceof Vector) { + if (value instanceof VectorValue) { return value.elements; } - if (value instanceof Matrix) { + if (value instanceof MatrixValue) { return value.elements.flat(); } + if (value instanceof ArrayValue) { + return value.elements; + } throw new Error(`unhandled value ${value}`); } +/** @returns the scalar elements of the given Value */ +export function scalarElementsOf(value: Value): ScalarValue[] { + if (isScalarValue(value)) { + return [value]; + } + if (value instanceof VectorValue) { + return value.elements; + } + if (value instanceof MatrixValue) { + return value.elements.flat(); + } + if (value instanceof ArrayValue) { + return value.elements.map(els => scalarElementsOf(els)).flat(); + } + throw new Error(`unhandled value ${value}`); +} + +/** @returns the inner element type of the given type */ +export function elementTypeOf(t: Type) { + if (t instanceof ScalarType) { + return t; + } + return t.elementType; +} + /** @returns the scalar (element) type of the given Type */ export function scalarTypeOf(ty: Type): ScalarType { if (ty instanceof ScalarType) { @@ -910,27 +1068,40 @@ export function scalarTypeOf(ty: Type): ScalarType { if (ty instanceof MatrixType) { return ty.elementType; } + if (ty instanceof ArrayType) { + return scalarTypeOf(ty.elementType); + } throw new Error(`unhandled type ${ty}`); } -/** ScalarValue is the JS type that can be held by a Scalar */ -type ScalarValue = boolean | number | bigint; +function hex(sizeInBytes: number, bitsLow: number, bitsHigh?: number) { + let hex = ''; + workingDataU32[0] = bitsLow; + if (bitsHigh !== undefined) { + workingDataU32[1] = bitsHigh; + } + for (let i = 0; i < sizeInBytes; ++i) { + hex = workingDataU8[i].toString(16).padStart(2, '0') + hex; + } + return `0x${hex}`; +} -/** Class that encapsulates a single scalar value of various types. */ -export class Scalar { - readonly value: ScalarValue; // The scalar value - readonly type: ScalarType; // The type of the scalar +function withPoint(x: number) { + const str = `${x}`; + return str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; +} - // The scalar value, packed in one or two 32-bit unsigned integers. - // Whether or not the bits1 is used depends on `this.type.size`. - readonly bits1: number; - readonly bits0: number; +/** Class that encapsulates a single abstract-int value. */ +export class AbstractIntValue { + readonly value: bigint; // The abstract-integer value + readonly bitsLow: number; // The low 32 bits of the abstract-integer value. + readonly bitsHigh: number; // The high 32 bits of the abstract-integer value. + readonly type = Type.abstractInt; // The type of the value. - public constructor(type: ScalarType, value: ScalarValue, bits1: number, bits0: number) { + public constructor(value: bigint, bitsLow: number, bitsHigh: number) { this.value = value; - this.type = type; - this.bits1 = bits1; - this.bits0 = bits0; + this.bitsLow = bitsLow; + this.bitsHigh = bitsHigh; } /** @@ -939,229 +1110,583 @@ export class Scalar { * @param offset the offset in buffer, in units of `buffer` */ public copyTo(buffer: TypedArrayBufferView, offset: number) { - assert( - this.type.kind !== 'abstract-int', - `Copying 'abstract-int' values to/from buffers is yet implemented` - ); - assert(this.type.kind !== 'f64', `Copying f64 values to/from buffers is not defined`); - workingDataU32[1] = this.bits1; - workingDataU32[0] = this.bits0; - for (let i = 0; i < this.type.size; i++) { + workingDataU32[0] = this.bitsLow; + workingDataU32[1] = this.bitsHigh; + for (let i = 0; i < 8; i++) { buffer[offset + i] = workingDataU8[i]; } } + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + // WGSL parses negative numbers as a negated positive. + // This means '-9223372036854775808' parses as `-' & '9223372036854775808', so must be written as + // '(-9223372036854775807 - 1)' in WGSL, because '9223372036854775808' is not a valid AbstractInt. + if (this.value === -9223372036854775808n) { + return `(-9223372036854775807 - 1)`; + } + return `${this.value}`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(8, this.bitsLow, this.bitsHigh)})`; + } +} + +/** Class that encapsulates a single abstract-float value. */ +export class AbstractFloatValue { + readonly value: number; // The f32 value + readonly bitsLow: number; // The low 32 bits of the abstract-float value. + readonly bitsHigh: number; // The high 32 bits of the abstract-float value. + readonly type = Type.abstractFloat; // The type of the value. + + public constructor(value: number, bitsLow: number, bitsHigh: number) { + this.value = value; + this.bitsLow = bitsLow; + this.bitsHigh = bitsHigh; + } + /** - * @returns the WGSL representation of this scalar value + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU32[0] = this.bitsLow; + workingDataU32[1] = this.bitsHigh; + for (let i = 0; i < 8; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ public wgsl(): string { - const withPoint = (x: number) => { - const str = `${x}`; - return str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; - }; + return `${withPoint(this.value)}`; + } - switch (typeof this.value) { - case 'bigint': - if (this.type.kind === 'abstract-int') { - // WGSL parses negative numbers as a negated positive. - // This means '-9223372036854775808' parses as `-' & - // '9223372036854775808', so must be written as - // '(-9223372036854775807 - 1)' in WGSL, because '9223372036854775808' - // is not a valid AbstractInt. - if (this.value === -9223372036854775808n) { - return `(-9223372036854775807 - 1)`; - } - return `${this.value}`; - } - break; - case 'number': - if (!isFinite(this.value)) break; - switch (this.type.kind) { - case 'abstract-float': - return `${withPoint(this.value)}`; - case 'f64': - return `${withPoint(this.value)}`; - case 'f32': - return `${withPoint(this.value)}f`; - case 'f16': - return `${withPoint(this.value)}h`; - case 'u32': - return `${this.value}u`; - case 'i32': - return `i32(${this.value})`; - } - break; - case 'boolean': - return `${this.value}`; + public toString(): string { + switch (this.value) { + case Infinity: + case -Infinity: + return Colors.bold(this.value.toString()); + default: { + let str = this.value.toString(); + str = str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; + return isSubnormalNumberF64(this.value.valueOf()) + ? `${Colors.bold(str)} (${hex(8, this.bitsLow, this.bitsHigh)} subnormal)` + : `${Colors.bold(str)} (${hex(8, this.bitsLow, this.bitsHigh)})`; + } } + } +} - throw new Error( - `scalar of value ${this.value} and type ${this.type} has no WGSL representation` - ); +/** Class that encapsulates a single i32 value. */ +export class I32Value { + readonly value: number; // The i32 value + readonly bits: number; // The i32 value, bitcast to a 32-bit integer. + readonly type = Type.i32; // The type of the value. + + public constructor(value: number, bits: number) { + this.value = value; + this.bits = bits; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU32[0] = this.bits; + for (let i = 0; i < 4; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `i32(${this.value})`; } public toString(): string { - if (this.type.kind === 'bool') { - return Colors.bold(this.value.toString()); + return `${Colors.bold(this.value.toString())} (${hex(4, this.bits)})`; + } +} + +/** Class that encapsulates a single u32 value. */ +export class U32Value { + readonly value: number; // The u32 value + readonly type = Type.u32; // The type of the value. + + public constructor(value: number) { + this.value = value; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU32[0] = this.value; + for (let i = 0; i < 4; i++) { + buffer[offset + i] = workingDataU8[i]; } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `${this.value}u`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(4, this.value)})`; + } +} + +/** + * Class that encapsulates a single i16 value. + * @note type does not exist in WGSL yet + */ +export class I16Value { + readonly value: number; // The i16 value + readonly bits: number; // The i16 value, bitcast to a 16-bit integer. + readonly type = Type.i16; // The type of the value. + + public constructor(value: number, bits: number) { + this.value = value; + this.bits = bits; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU16[0] = this.bits; + for (let i = 0; i < 4; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `i16(${this.value})`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(2, this.bits)})`; + } +} + +/** + * Class that encapsulates a single u16 value. + * @note type does not exist in WGSL yet + */ +export class U16Value { + readonly value: number; // The u16 value + readonly type = Type.u16; // The type of the value. + + public constructor(value: number) { + this.value = value; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU16[0] = this.value; + for (let i = 0; i < 2; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + assert(false, 'u16 is not a WGSL type'); + return `u16(${this.value})`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(2, this.value)})`; + } +} + +/** + * Class that encapsulates a single i8 value. + * @note type does not exist in WGSL yet + */ +export class I8Value { + readonly value: number; // The i8 value + readonly bits: number; // The i8 value, bitcast to a 8-bit integer. + readonly type = Type.i8; // The type of the value. + + public constructor(value: number, bits: number) { + this.value = value; + this.bits = bits; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU8[0] = this.bits; + for (let i = 0; i < 4; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `i8(${this.value})`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(2, this.bits)})`; + } +} + +/** + * Class that encapsulates a single u8 value. + * @note type does not exist in WGSL yet + */ +export class U8Value { + readonly value: number; // The u8 value + readonly type = Type.u8; // The type of the value. + + public constructor(value: number) { + this.value = value; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU8[0] = this.value; + for (let i = 0; i < 2; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + assert(false, 'u8 is not a WGSL type'); + return `u8(${this.value})`; + } + + public toString(): string { + return `${Colors.bold(this.value.toString())} (${hex(2, this.value)})`; + } +} + +/** + * Class that encapsulates a single f64 value + * @note type does not exist in WGSL yet + */ +export class F64Value { + readonly value: number; // The f32 value + readonly bitsLow: number; // The low 32 bits of the abstract-float value. + readonly bitsHigh: number; // The high 32 bits of the abstract-float value. + readonly type = Type.f64; // The type of the value. + + public constructor(value: number, bitsLow: number, bitsHigh: number) { + this.value = value; + this.bitsLow = bitsLow; + this.bitsHigh = bitsHigh; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU32[0] = this.bitsLow; + workingDataU32[1] = this.bitsHigh; + for (let i = 0; i < 8; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + assert(false, 'f64 is not a WGSL type'); + return `${withPoint(this.value)}`; + } + + public toString(): string { switch (this.value) { case Infinity: case -Infinity: return Colors.bold(this.value.toString()); default: { - workingDataU32[1] = this.bits1; - workingDataU32[0] = this.bits0; - let hex = ''; - for (let i = 0; i < this.type.size; ++i) { - hex = workingDataU8[i].toString(16).padStart(2, '0') + hex; - } - const n = this.value as Number; - if (n !== null && isFloatValue(this)) { - let str = this.value.toString(); - str = str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; - switch (this.type.kind) { - case 'abstract-float': - return isSubnormalNumberF64(n.valueOf()) - ? `${Colors.bold(str)} (0x${hex} subnormal)` - : `${Colors.bold(str)} (0x${hex})`; - case 'f64': - return isSubnormalNumberF64(n.valueOf()) - ? `${Colors.bold(str)} (0x${hex} subnormal)` - : `${Colors.bold(str)} (0x${hex})`; - case 'f32': - return isSubnormalNumberF32(n.valueOf()) - ? `${Colors.bold(str)} (0x${hex} subnormal)` - : `${Colors.bold(str)} (0x${hex})`; - case 'f16': - return isSubnormalNumberF16(n.valueOf()) - ? `${Colors.bold(str)} (0x${hex} subnormal)` - : `${Colors.bold(str)} (0x${hex})`; - default: - unreachable( - `Printing of floating point kind ${this.type.kind} is not implemented...` - ); - } - } - return `${Colors.bold(this.value.toString())} (0x${hex})`; + let str = this.value.toString(); + str = str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; + return isSubnormalNumberF64(this.value.valueOf()) + ? `${Colors.bold(str)} (${hex(8, this.bitsLow, this.bitsHigh)} subnormal)` + : `${Colors.bold(str)} (${hex(8, this.bitsLow, this.bitsHigh)})`; } } } } -export interface ScalarBuilder { - (value: T): Scalar; +/** Class that encapsulates a single f32 value. */ +export class F32Value { + readonly value: number; // The f32 value + readonly bits: number; // The f32 value, bitcast to a 32-bit integer. + readonly type = Type.f32; // The type of the value. + + public constructor(value: number, bits: number) { + this.value = value; + this.bits = bits; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU32[0] = this.bits; + for (let i = 0; i < 4; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `${withPoint(this.value)}f`; + } + + public toString(): string { + switch (this.value) { + case Infinity: + case -Infinity: + return Colors.bold(this.value.toString()); + default: { + let str = this.value.toString(); + str = str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; + return isSubnormalNumberF32(this.value.valueOf()) + ? `${Colors.bold(str)} (${hex(4, this.bits)} subnormal)` + : `${Colors.bold(str)} (${hex(4, this.bits)})`; + } + } + } } -/** Create a Scalar of `type` by storing `value` as an element of `workingDataArray` and retrieving it. - * The working data array *must* be an alias of `workingData`. - */ -function scalarFromValue( - type: ScalarType, - workingDataArray: A, - value: ArrayElementType -): Scalar { - // Clear all bits of the working data since `value` may be smaller; the upper bits should be 0. - workingDataU32[1] = 0; - workingDataU32[0] = 0; - workingDataArray[0] = value; - return new Scalar(type, workingDataArray[0], workingDataU32[1], workingDataU32[0]); -} - -/** Create a Scalar of `type` by storing `value` as an element of `workingDataStoreArray` and - * reinterpreting it as an element of `workingDataLoadArray`. - * Both working data arrays *must* be aliases of `workingData`. - */ -function scalarFromBits( - type: ScalarType, - workingDataStoreArray: A, - workingDataLoadArray: TypedArrayBufferView, - bits: ArrayElementType -): Scalar { - // Clear all bits of the working data since `value` may be smaller; the upper bits should be 0. - workingDataU32[1] = 0; - workingDataU32[0] = 0; - workingDataStoreArray[0] = bits; - return new Scalar(type, workingDataLoadArray[0], workingDataU32[1], workingDataU32[0]); +/** Class that encapsulates a single f16 value. */ +export class F16Value { + readonly value: number; // The f16 value + readonly bits: number; // The f16 value, bitcast to a 16-bit integer. + readonly type = Type.f16; // The type of the value. + + public constructor(value: number, bits: number) { + this.value = value; + this.bits = bits; + } + + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + workingDataU16[0] = this.bits; + for (let i = 0; i < 2; i++) { + buffer[offset + i] = workingDataU8[i]; + } + } + + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return `${withPoint(this.value)}h`; + } + + public toString(): string { + switch (this.value) { + case Infinity: + case -Infinity: + return Colors.bold(this.value.toString()); + default: { + let str = this.value.toString(); + str = str.indexOf('.') > 0 || str.indexOf('e') > 0 ? str : `${str}.0`; + return isSubnormalNumberF16(this.value.valueOf()) + ? `${Colors.bold(str)} (${hex(2, this.bits)} subnormal)` + : `${Colors.bold(str)} (${hex(2, this.bits)})`; + } + } + } } +/** Class that encapsulates a single bool value. */ +export class BoolValue { + readonly value: boolean; // The bool value + readonly type = Type.bool; // The type of the value. -/** Create an AbstractFloat from a numeric value, a JS `number`. */ -export const abstractFloat = (value: number): Scalar => - scalarFromValue(TypeAbstractFloat, workingDataF64, value); + public constructor(value: boolean) { + this.value = value; + } -/** Create an f64 from a numeric value, a JS `number`. */ -export const f64 = (value: number): Scalar => scalarFromValue(TypeF64, workingDataF64, value); + /** + * Copies the scalar value to the buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the offset in buffer, in units of `buffer` + */ + public copyTo(buffer: TypedArrayBufferView, offset: number) { + buffer[offset] = this.value ? 1 : 0; + } -/** Create an f32 from a numeric value, a JS `number`. */ -export const f32 = (value: number): Scalar => scalarFromValue(TypeF32, workingDataF32, value); + /** @returns the WGSL representation of this scalar value */ + public wgsl(): string { + return this.value.toString(); + } -/** Create an f16 from a numeric value, a JS `number`. */ -export const f16 = (value: number): Scalar => scalarFromValue(TypeF16, workingDataF16, value); + public toString(): string { + return Colors.bold(this.value.toString()); + } +} -/** Create an f32 from a bit representation, a uint32 represented as a JS `number`. */ -export const f32Bits = (bits: number): Scalar => - scalarFromBits(TypeF32, workingDataU32, workingDataF32, bits); +/** Scalar represents all the scalar value types */ +export type ScalarValue = + | AbstractIntValue + | AbstractFloatValue + | I32Value + | U32Value + | I16Value + | U16Value + | I8Value + | U8Value + | F64Value + | F32Value + | F16Value + | BoolValue; -/** Create an f16 from a bit representation, a uint16 represented as a JS `number`. */ -export const f16Bits = (bits: number): Scalar => - scalarFromBits(TypeF16, workingDataU16, workingDataF16, bits); +export interface ScalarBuilder { + (value: T): ScalarValue; +} -/** Create an AbstractInt from a numeric value, a JS `bigint`. */ -export const abstractInt = (value: bigint): Scalar => - scalarFromValue(TypeAbstractInt, workingDataI64, value); +export function isScalarValue(value: object): value is ScalarValue { + return ( + value instanceof AbstractIntValue || + value instanceof AbstractFloatValue || + value instanceof I32Value || + value instanceof U32Value || + value instanceof I16Value || + value instanceof U16Value || + value instanceof I8Value || + value instanceof U8Value || + value instanceof F64Value || + value instanceof F32Value || + value instanceof F16Value || + value instanceof BoolValue + ); +} -export const abstractIntBits = (bits: bigint): Scalar => - scalarFromBits(TypeAbstractInt, workingDataU64, workingDataI64, bits); +/** Create an AbstractInt from a numeric value, a JS `bigint`. */ +export function abstractInt(value: bigint) { + workingDataI64[0] = value; + return new AbstractIntValue(workingDataI64[0], workingDataU32[0], workingDataU32[1]); +} -/** Create an i32 from a numeric value, a JS `number`. */ -export const i32 = (value: number): Scalar => scalarFromValue(TypeI32, workingDataI32, value); +/** Create an AbstractInt from a bit representation, a uint64 represented as a JS `bigint`. */ +export function abstractIntBits(value: bigint) { + workingDataU64[0] = value; + return new AbstractIntValue(workingDataI64[0], workingDataU32[0], workingDataU32[1]); +} -/** Create an i16 from a numeric value, a JS `number`. */ -export const i16 = (value: number): Scalar => scalarFromValue(TypeI16, workingDataI16, value); +/** Create an AbstractFloat from a numeric value, a JS `number`. */ +export function abstractFloat(value: number) { + workingDataF64[0] = value; + return new AbstractFloatValue(workingDataF64[0], workingDataU32[0], workingDataU32[1]); +} -/** Create an i8 from a numeric value, a JS `number`. */ -export const i8 = (value: number): Scalar => scalarFromValue(TypeI8, workingDataI8, value); +/** Create an i32 from a numeric value, a JS `number`. */ +export function i32(value: number) { + workingDataI32[0] = value; + return new I32Value(workingDataI32[0], workingDataU32[0]); +} /** Create an i32 from a bit representation, a uint32 represented as a JS `number`. */ -export const i32Bits = (bits: number): Scalar => - scalarFromBits(TypeI32, workingDataU32, workingDataI32, bits); +export function i32Bits(bits: number) { + workingDataU32[0] = bits; + return new I32Value(workingDataI32[0], workingDataU32[0]); +} -/** Create an i16 from a bit representation, a uint16 represented as a JS `number`. */ -export const i16Bits = (bits: number): Scalar => - scalarFromBits(TypeI16, workingDataU16, workingDataI16, bits); +/** Create a u32 from a numeric value, a JS `number`. */ +export function u32(value: number) { + workingDataU32[0] = value; + return new U32Value(workingDataU32[0]); +} -/** Create an i8 from a bit representation, a uint8 represented as a JS `number`. */ -export const i8Bits = (bits: number): Scalar => - scalarFromBits(TypeI8, workingDataU8, workingDataI8, bits); +/** Create a u32 from a bit representation, a uint32 represented as a JS `number`. */ +export function u32Bits(bits: number) { + workingDataU32[0] = bits; + return new U32Value(workingDataU32[0]); +} -/** Create a u32 from a numeric value, a JS `number`. */ -export const u32 = (value: number): Scalar => scalarFromValue(TypeU32, workingDataU32, value); +/** Create an i16 from a numeric value, a JS `number`. */ +export function i16(value: number) { + workingDataI16[0] = value; + return new I16Value(workingDataI16[0], workingDataU16[0]); +} /** Create a u16 from a numeric value, a JS `number`. */ -export const u16 = (value: number): Scalar => scalarFromValue(TypeU16, workingDataU16, value); +export function u16(value: number) { + workingDataU16[0] = value; + return new U16Value(workingDataU16[0]); +} + +/** Create an i8 from a numeric value, a JS `number`. */ +export function i8(value: number) { + workingDataI8[0] = value; + return new I8Value(workingDataI8[0], workingDataU8[0]); +} /** Create a u8 from a numeric value, a JS `number`. */ -export const u8 = (value: number): Scalar => scalarFromValue(TypeU8, workingDataU8, value); +export function u8(value: number) { + workingDataU8[0] = value; + return new U8Value(workingDataU8[0]); +} + +/** Create an f64 from a numeric value, a JS `number`. */ +export function f64(value: number) { + workingDataF64[0] = value; + return new F64Value(workingDataF64[0], workingDataU32[0], workingDataU32[1]); +} -/** Create an u32 from a bit representation, a uint32 represented as a JS `number`. */ -export const u32Bits = (bits: number): Scalar => - scalarFromBits(TypeU32, workingDataU32, workingDataU32, bits); +/** Create an f32 from a numeric value, a JS `number`. */ +export function f32(value: number) { + workingDataF32[0] = value; + return new F32Value(workingDataF32[0], workingDataU32[0]); +} + +/** Create an f32 from a bit representation, a uint32 represented as a JS `number`. */ +export function f32Bits(bits: number) { + workingDataU32[0] = bits; + return new F32Value(workingDataF32[0], workingDataU32[0]); +} -/** Create an u16 from a bit representation, a uint16 represented as a JS `number`. */ -export const u16Bits = (bits: number): Scalar => - scalarFromBits(TypeU16, workingDataU16, workingDataU16, bits); +/** Create an f16 from a numeric value, a JS `number`. */ +export function f16(value: number) { + workingDataF16[0] = value; + return new F16Value(value, workingDataU16[0]); +} -/** Create an u8 from a bit representation, a uint8 represented as a JS `number`. */ -export const u8Bits = (bits: number): Scalar => - scalarFromBits(TypeU8, workingDataU8, workingDataU8, bits); +/** Create an f16 from a bit representation, a uint16 represented as a JS `number`. */ +export function f16Bits(bits: number) { + workingDataU16[0] = bits; + return new F16Value(workingDataF16[0], workingDataU16[0]); +} /** Create a boolean value. */ -export function bool(value: boolean): Scalar { - // WGSL does not support using 'bool' types directly in storage / uniform - // buffers, so instead we pack booleans in a u32, where 'false' is zero and - // 'true' is any non-zero value. - workingDataU32[0] = value ? 1 : 0; - workingDataU32[1] = 0; - return new Scalar(TypeBool, value, workingDataU32[1], workingDataU32[0]); +export function bool(value: boolean): ScalarValue { + return new BoolValue(value); } /** A 'true' literal value */ @@ -1173,11 +1698,11 @@ export const False = bool(false); /** * Class that encapsulates a vector value. */ -export class Vector { - readonly elements: Array; +export class VectorValue { + readonly elements: Array; readonly type: VectorType; - public constructor(elements: Array) { + public constructor(elements: Array) { if (elements.length < 2 || elements.length > 4) { throw new Error(`vector element count must be between 2 and 4, got ${elements.length}`); } @@ -1191,7 +1716,7 @@ export class Vector { } } this.elements = elements; - this.type = TypeVec(elements.length, elements[0].type); + this.type = VectorType.create(elements.length, elements[0].type); } /** @@ -1240,18 +1765,18 @@ export class Vector { } /** Helper for constructing a new two-element vector with the provided values */ -export function vec2(x: Scalar, y: Scalar) { - return new Vector([x, y]); +export function vec2(x: ScalarValue, y: ScalarValue) { + return new VectorValue([x, y]); } /** Helper for constructing a new three-element vector with the provided values */ -export function vec3(x: Scalar, y: Scalar, z: Scalar) { - return new Vector([x, y, z]); +export function vec3(x: ScalarValue, y: ScalarValue, z: ScalarValue) { + return new VectorValue([x, y, z]); } /** Helper for constructing a new four-element vector with the provided values */ -export function vec4(x: Scalar, y: Scalar, z: Scalar, w: Scalar) { - return new Vector([x, y, z, w]); +export function vec4(x: ScalarValue, y: ScalarValue, z: ScalarValue, w: ScalarValue) { + return new VectorValue([x, y, z, w]); } /** @@ -1260,7 +1785,7 @@ export function vec4(x: Scalar, y: Scalar, z: Scalar, w: Scalar) { * @param v array of numbers to be converted, must contain 2, 3 or 4 elements * @param op function to convert from number to Scalar, e.g. 'f32` */ -export function toVector(v: readonly number[], op: (n: number) => Scalar): Vector { +export function toVector(v: readonly number[], op: (n: number) => ScalarValue): VectorValue { switch (v.length) { case 2: return vec2(op(v[0]), op(v[1])); @@ -1275,11 +1800,11 @@ export function toVector(v: readonly number[], op: (n: number) => Scalar): Vecto /** * Class that encapsulates a Matrix value. */ -export class Matrix { - readonly elements: Scalar[][]; +export class MatrixValue { + readonly elements: ScalarValue[][]; readonly type: MatrixType; - public constructor(elements: Array>) { + public constructor(elements: Array>) { const num_cols = elements.length; if (num_cols < 2 || num_cols > 4) { throw new Error(`matrix cols count must be between 2 and 4, got ${num_cols}`); @@ -1300,7 +1825,7 @@ export class Matrix { } this.elements = elements; - this.type = TypeMat(num_cols, num_rows, elem_type); + this.type = MatrixType.create(num_cols, num_rows, elem_type); } /** @@ -1335,6 +1860,48 @@ export class Matrix { } } +/** + * Class that encapsulates an Array value. + */ +export class ArrayValue { + readonly elements: Value[]; + readonly type: ArrayType; + + public constructor(elements: Array) { + const elem_type = elements[0].type; + if (!elements.every(c => elements.every(r => objectEquals(r.type, elem_type)))) { + throw new Error(`cannot mix array element types`); + } + + this.elements = elements; + this.type = ArrayType.create(elements.length, elem_type); + } + + /** + * Copies the matrix value to the Uint8Array buffer at the provided byte offset. + * @param buffer the destination buffer + * @param offset the byte offset within buffer + */ + public copyTo(buffer: Uint8Array, offset: number) { + for (const element of this.elements) { + element.copyTo(buffer, offset); + offset += this.type.elementType.size; + } + } + + /** + * @returns the WGSL representation of this matrix value + */ + public wgsl(): string { + const els = this.elements.map(r => r.wgsl()).join(', '); + return `${this.type}(${els})`; + } + + public toString(): string { + return this.wgsl(); + } +} + /** * Helper for constructing Matrices from arrays of numbers * @@ -1342,35 +1909,37 @@ export class Matrix { * be of the same length. All Arrays must have 2, 3, or 4 elements. * @param op function to convert from number to Scalar, e.g. 'f32` */ -export function toMatrix(m: ROArrayArray, op: (n: number) => Scalar): Matrix { +export function toMatrix(m: ROArrayArray, op: (n: number) => ScalarValue): MatrixValue { const cols = m.length; const rows = m[0].length; - const elements: Scalar[][] = [...Array(cols)].map(_ => [...Array(rows)]); + const elements: ScalarValue[][] = [...Array(cols)].map(_ => [ + ...Array(rows), + ]); for (let i = 0; i < cols; i++) { for (let j = 0; j < rows; j++) { elements[i][j] = op(m[i][j]); } } - return new Matrix(elements); + return new MatrixValue(elements); } -/** Value is a Scalar or Vector value. */ -export type Value = Scalar | Vector | Matrix; +/** Value is a Scalar, Vector, Matrix or Array value. */ +export type Value = ScalarValue | VectorValue | MatrixValue | ArrayValue; -export type SerializedValueScalar = { +export type SerializedScalarValue = { kind: 'scalar'; type: ScalarKind; value: boolean | number; }; -export type SerializedValueVector = { +export type SerializedVectorValue = { kind: 'vector'; type: ScalarKind; value: boolean[] | readonly number[]; }; -export type SerializedValueMatrix = { +export type SerializedMatrixValue = { kind: 'matrix'; type: ScalarKind; value: ROArrayArray; @@ -1475,7 +2044,7 @@ enum SerializedValueKind { /** serializeValue() serializes a Value to a BinaryStream */ export function serializeValue(s: BinaryStream, v: Value) { - const serializeScalar = (scalar: Scalar, kind: ScalarKind) => { + const serializeScalar = (scalar: ScalarValue, kind: ScalarKind) => { switch (typeof scalar.value) { case 'number': switch (kind) { @@ -1528,13 +2097,13 @@ export function serializeValue(s: BinaryStream, v: Value) { } }; - if (v instanceof Scalar) { + if (isScalarValue(v)) { s.writeU8(SerializedValueKind.Scalar); serializeScalarKind(s, v.type.kind); serializeScalar(v, v.type.kind); return; } - if (v instanceof Vector) { + if (v instanceof VectorValue) { s.writeU8(SerializedValueKind.Vector); serializeScalarKind(s, v.type.elementType.kind); s.writeU8(v.type.width); @@ -1543,7 +2112,7 @@ export function serializeValue(s: BinaryStream, v: Value) { } return; } - if (v instanceof Matrix) { + if (v instanceof MatrixValue) { s.writeU8(SerializedValueKind.Matrix); serializeScalarKind(s, v.type.elementType.kind); s.writeU8(v.type.cols); @@ -1596,23 +2165,23 @@ export function deserializeValue(s: BinaryStream): Value { return deserializeScalar(scalarKind); case SerializedValueKind.Vector: { const width = s.readU8(); - const scalars = new Array(width); + const scalars = new Array(width); for (let i = 0; i < width; i++) { scalars[i] = deserializeScalar(scalarKind); } - return new Vector(scalars); + return new VectorValue(scalars); } case SerializedValueKind.Matrix: { const numCols = s.readU8(); const numRows = s.readU8(); - const columns = new Array(numCols); + const columns = new Array(numCols); for (let c = 0; c < numCols; c++) { - columns[c] = new Array(numRows); + columns[c] = new Array(numRows); for (let i = 0; i < numRows; i++) { columns[c][i] = deserializeScalar(scalarKind); } } - return new Matrix(columns); + return new MatrixValue(columns); } default: unreachable(`invalid serialized value kind: ${valueKind}`); @@ -1651,70 +2220,31 @@ export function isFloatType(ty: Type): boolean { } /// All floating-point scalar types -export const kAllFloatScalars = [TypeAbstractFloat, TypeF32, TypeF16] as const; +const kFloatScalars = [Type.abstractFloat, Type.f32, Type.f16] as const; /// All floating-point vec2 types -export const kAllFloatVector2 = [ - TypeVec(2, TypeAbstractFloat), - TypeVec(2, TypeF32), - TypeVec(2, TypeF16), -] as const; +const kFloatVec2 = [Type.vec(2, Type.abstractFloat), Type.vec2f, Type.vec2h] as const; /// All floating-point vec3 types -export const kAllFloatVector3 = [ - TypeVec(3, TypeAbstractFloat), - TypeVec(3, TypeF32), - TypeVec(3, TypeF16), -] as const; +const kFloatVec3 = [Type.vec(3, Type.abstractFloat), Type.vec3f, Type.vec3h] as const; /// All floating-point vec4 types -export const kAllFloatVector4 = [ - TypeVec(4, TypeAbstractFloat), - TypeVec(4, TypeF32), - TypeVec(4, TypeF16), -] as const; - -/// All floating-point vector types -export const kAllFloatVectors = [ - ...kAllFloatVector2, - ...kAllFloatVector3, - ...kAllFloatVector4, -] as const; +const kFloatVec4 = [Type.vec(4, Type.abstractFloat), Type.vec4f, Type.vec4h] as const; /// All f16 floating-point scalar and vector types -export const kAllF16ScalarsAndVectors = [ - TypeF16, - TypeVec(2, TypeF16), - TypeVec(3, TypeF16), - TypeVec(4, TypeF16), +export const kConcreteF16ScalarsAndVectors = [ + Type.f16, + Type.vec2h, + Type.vec3h, + Type.vec4h, ] as const; /// All floating-point scalar and vector types -export const kAllFloatScalarsAndVectors = [...kAllFloatScalars, ...kAllFloatVectors] as const; - -/// Abstract integer scalar type -export const kAbstractIntegerScalar = [TypeAbstractInt] as const; - -/// Abstract integer vec2 type -export const kAbstractIntegerVector2 = [TypeVec(2, TypeAbstractInt)] as const; - -/// Abstract integer vec3 type -export const kAbstractIntegerVector3 = [TypeVec(3, TypeAbstractInt)] as const; - -/// Abstract integer vec4 type -export const kAbstractIntegerVector4 = [TypeVec(4, TypeAbstractInt)] as const; - -/// All abstract integer scalar vector types -export const kAbstractIntegerVectors = [ - ...kAbstractIntegerVector2, - ...kAbstractIntegerVector3, - ...kAbstractIntegerVector4, -] as const; - -/// Abstract integer scalar and vector types -export const kAllAbstractIntegerScalarAndVectors = [ - ...kAbstractIntegerScalar, - ...kAbstractIntegerVectors, +export const kFloatScalarsAndVectors = [ + ...kFloatScalars, + ...kFloatVec2, + ...kFloatVec3, + ...kFloatVec4, ] as const; // Abstract and concrete integer types are not grouped into an 'all' type, @@ -1725,49 +2255,56 @@ export const kAllAbstractIntegerScalarAndVectors = [ // for the things that might be valid and those that are never valid. /// All concrete integer scalar and vector types -export const kAllConcreteIntegerScalarsAndVectors = [ - TypeI32, - TypeVec(2, TypeI32), - TypeVec(3, TypeI32), - TypeVec(4, TypeI32), - TypeU32, - TypeVec(2, TypeU32), - TypeVec(3, TypeU32), - TypeVec(4, TypeU32), +export const kConcreteIntegerScalarsAndVectors = [ + Type.i32, + Type.vec2i, + Type.vec3i, + Type.vec4i, + Type.u32, + Type.vec2u, + Type.vec3u, + Type.vec4u, ] as const; /// All signed integer scalar and vector types -export const kAllSignedIntegerScalarsAndVectors = [ - TypeI32, - TypeVec(2, TypeI32), - TypeVec(3, TypeI32), - TypeVec(4, TypeI32), +export const kConcreteSignedIntegerScalarsAndVectors = [ + Type.i32, + Type.vec2i, + Type.vec3i, + Type.vec4i, ] as const; /// All unsigned integer scalar and vector types -export const kAllUnsignedIntegerScalarsAndVectors = [ - TypeU32, - TypeVec(2, TypeU32), - TypeVec(3, TypeU32), - TypeVec(4, TypeU32), +export const kConcreteUnsignedIntegerScalarsAndVectors = [ + Type.u32, + Type.vec2u, + Type.vec3u, + Type.vec4u, ] as const; -/// All floating-point and integer scalar and vector types -export const kAllFloatAndConcreteIntegerScalarsAndVectors = [ - ...kAllFloatScalarsAndVectors, - ...kAllConcreteIntegerScalarsAndVectors, -] as const; +/// All types which are convertable to floating-point scalar types. +export const kConvertableToFloatScalar = [Type.abstractInt, ...kFloatScalars] as const; + +/// All types which are convertable to floating-point vector 2 types. +export const kConvertableToFloatVec2 = [Type.vec(2, Type.abstractInt), ...kFloatVec2] as const; + +/// All types which are convertable to floating-point vector 3 types. +export const kConvertableToFloatVec3 = [Type.vec(3, Type.abstractInt), ...kFloatVec3] as const; + +/// All types which are convertable to floating-point vector 4 types. +export const kConvertableToFloatVec4 = [Type.vec(4, Type.abstractInt), ...kFloatVec4] as const; -/// All floating-point and signed integer scalar and vector types -export const kAllFloatAndSignedIntegerScalarsAndVectors = [ - ...kAllFloatScalarsAndVectors, - ...kAllSignedIntegerScalarsAndVectors, +/// All types which are convertable to floating-point scalar or vector types. +export const kConvertableToFloatScalarsAndVectors = [ + Type.abstractInt, + Type.vec(2, Type.abstractInt), + Type.vec(3, Type.abstractInt), + Type.vec(4, Type.abstractInt), + ...kFloatScalarsAndVectors, ] as const; -/** @returns the inner element type of the given type */ -export function elementType(t: ScalarType | VectorType | MatrixType) { - if (t instanceof ScalarType) { - return t; - } - return t.elementType; -} +/// All the scalar and vector types +export const kAllScalarsAndVectors = [ + ...kConvertableToFloatScalarsAndVectors, + ...kConcreteIntegerScalarsAndVectors, +] as const; diff --git a/src/webgpu/util/device_pool.ts b/src/webgpu/util/device_pool.ts index 4e45aac76bb8..d0d1e6c0b6b5 100644 --- a/src/webgpu/util/device_pool.ts +++ b/src/webgpu/util/device_pool.ts @@ -24,16 +24,27 @@ export class TestOOMedShouldAttemptGC extends Error {} export class DevicePool { private holders: 'uninitialized' | 'failed' | DescriptorToHolderMap = 'uninitialized'; + async requestAdapter(recorder: TestCaseRecorder) { + const gpu = getGPU(recorder); + const adapter = await gpu.requestAdapter(); + assert(adapter !== null, 'requestAdapter returned null'); + return adapter; + } + /** Acquire a device from the pool and begin the error scopes. */ async acquire( - recorder: TestCaseRecorder, + adapter: GPUAdapter, descriptor?: UncanonicalizedDeviceDescriptor ): Promise { - let errorMessage = ''; + let holder; if (this.holders === 'uninitialized') { this.holders = new DescriptorToHolderMap(); + } + + let errorMessage = ''; + if (this.holders !== 'failed') { try { - await this.holders.getOrCreate(recorder, undefined); + holder = await this.holders.getOrCreate(adapter, descriptor); } catch (ex) { this.holders = 'failed'; if (ex instanceof Error) { @@ -46,9 +57,7 @@ export class DevicePool { this.holders !== 'failed', `WebGPU device failed to initialize${errorMessage}; not retrying` ); - - const holder = await this.holders.getOrCreate(recorder, descriptor); - + assert(!!holder); assert(holder.state === 'free', 'Device was in use on DevicePool.acquire'); holder.state = 'acquired'; holder.beginTestScope(); @@ -138,7 +147,7 @@ class DescriptorToHolderMap { * Throws SkipTestCase if devices with this descriptor are unsupported. */ async getOrCreate( - recorder: TestCaseRecorder, + adapter: GPUAdapter, uncanonicalizedDescriptor: UncanonicalizedDeviceDescriptor | undefined ): Promise { const [descriptor, key] = canonicalizeDescriptor(uncanonicalizedDescriptor); @@ -163,7 +172,7 @@ class DescriptorToHolderMap { // No existing item was found; add a new one. let value; try { - value = await DeviceHolder.create(recorder, descriptor); + value = await DeviceHolder.create(adapter, descriptor); } catch (ex) { if (ex instanceof FeaturesNotSupported) { this.unsupported.add(key); @@ -298,15 +307,14 @@ class DeviceHolder implements DeviceProvider { // Gets a device and creates a DeviceHolder. // If the device is lost, DeviceHolder.lost gets set. static async create( - recorder: TestCaseRecorder, + adapter: GPUAdapter, descriptor: CanonicalDeviceDescriptor | undefined ): Promise { - const gpu = getGPU(recorder); - const adapter = await gpu.requestAdapter(); - assert(adapter !== null, 'requestAdapter returned null'); + assert(adapter !== null, 'requestAdapter is null'); if (!supportsFeature(adapter, descriptor)) { throw new FeaturesNotSupported('One or more features are not supported'); } + const device = await adapter.requestDevice(descriptor); assert(device !== null, 'requestDevice returned null'); diff --git a/src/webgpu/util/floating_point.ts b/src/webgpu/util/floating_point.ts index 31b90081bfe6..9015eca362eb 100644 --- a/src/webgpu/util/floating_point.ts +++ b/src/webgpu/util/floating_point.ts @@ -12,7 +12,7 @@ import { f16, f32, isFloatType, - Scalar, + ScalarValue, ScalarType, toMatrix, toVector, @@ -1073,8 +1073,8 @@ export abstract class FPTraits { public abstract readonly flushSubnormal: (n: number) => number; /** @returns 1 * ULP: (number) */ public abstract readonly oneULP: (target: number, mode?: FlushMode) => number; - /** @returns a builder for converting numbers to Scalars */ - public abstract readonly scalarBuilder: (n: number) => Scalar; + /** @returns a builder for converting numbers to ScalarsValues */ + public abstract readonly scalarBuilder: (n: number) => ScalarValue; /** @returns a range of scalars for testing */ public abstract scalarRange(): readonly number[]; /** @returns a reduced range of scalars for testing */ @@ -5164,26 +5164,16 @@ class FPAbstractTraits extends FPTraits { public readonly mixIntervals = [this.mixImpreciseInterval, this.mixPreciseInterval]; public readonly modfInterval = this.modfIntervalImpl.bind(this); public readonly multiplicationInterval = this.multiplicationIntervalImpl.bind(this); - public readonly multiplicationMatrixMatrixInterval = this.unimplementedMatrixPairToMatrix.bind( - this, - 'multiplicationMatrixMatrixInterval' - ); - public readonly multiplicationMatrixScalarInterval = this.unimplementedMatrixScalarToMatrix.bind( - this, - 'multiplicationMatrixScalarInterval' - ); - public readonly multiplicationScalarMatrixInterval = this.unimplementedScalarMatrixToMatrix.bind( - this, - 'multiplicationScalarMatrixInterval' - ); - public readonly multiplicationMatrixVectorInterval = this.unimplementedMatrixVectorToVector.bind( - this, - 'multiplicationMatrixVectorInterval' - ); - public readonly multiplicationVectorMatrixInterval = this.unimplementedVectorMatrixToVector.bind( - this, - 'multiplicationVectorMatrixInterval' - ); + public readonly multiplicationMatrixMatrixInterval = + this.multiplicationMatrixMatrixIntervalImpl.bind(this); + public readonly multiplicationMatrixScalarInterval = + this.multiplicationMatrixScalarIntervalImpl.bind(this); + public readonly multiplicationScalarMatrixInterval = + this.multiplicationScalarMatrixIntervalImpl.bind(this); + public readonly multiplicationMatrixVectorInterval = + this.multiplicationMatrixVectorIntervalImpl.bind(this); + public readonly multiplicationVectorMatrixInterval = + this.multiplicationVectorMatrixIntervalImpl.bind(this); public readonly negationInterval = this.negationIntervalImpl.bind(this); public readonly normalizeInterval = this.unimplementedVectorToVector.bind( this, diff --git a/src/webgpu/web_platform/external_texture/video.spec.ts b/src/webgpu/web_platform/external_texture/video.spec.ts index 2b5e0bdb40a9..8e812ccd2a34 100644 --- a/src/webgpu/web_platform/external_texture/video.spec.ts +++ b/src/webgpu/web_platform/external_texture/video.spec.ts @@ -10,6 +10,7 @@ TODO(#3193): Test video in BT.2020 color space import { makeTestGroup } from '../../../common/framework/test_group.js'; import { GPUTest, TextureTestMixin } from '../../gpu_test.js'; +import { createCanvas } from '../../util/create_elements.js'; import { startPlayingAndWaitForVideo, getVideoFrameFromVideoElement, @@ -27,7 +28,10 @@ const kFormat = 'rgba8unorm'; export const g = makeTestGroup(TextureTestMixin(GPUTest)); -function createExternalTextureSamplingTestPipeline(t: GPUTest): GPURenderPipeline { +function createExternalTextureSamplingTestPipeline( + t: GPUTest, + colorAttachmentFormat: GPUTextureFormat = kFormat +): GPURenderPipeline { const pipeline = t.device.createRenderPipeline({ layout: 'auto', vertex: { @@ -63,7 +67,7 @@ function createExternalTextureSamplingTestPipeline(t: GPUTest): GPURenderPipelin entryPoint: 'main', targets: [ { - format: kFormat, + format: colorAttachmentFormat, }, ], }, @@ -228,6 +232,131 @@ for several combinations of video format, video color spaces and dst color space }); }); +g.test('importExternalTexture,sample_non_YUV_video_frame') + .desc( + ` +Tests that we can import an VideoFrame with non-YUV pixel format into a GPUExternalTexture and sample it. +` + ) + .params(u => + u // + .combine('videoFrameFormat', ['RGBA', 'RGBX', 'BGRA', 'BGRX'] as const) + ) + .fn(t => { + const { videoFrameFormat } = t.params; + + if (typeof VideoFrame === 'undefined') { + t.skip('WebCodec is not supported'); + } + + const canvas = createCanvas(t, 'onscreen', kWidth, kHeight); + + const canvasContext = canvas.getContext('2d'); + + if (canvasContext === null) { + t.skip(' onscreen canvas 2d context not available'); + } + + const ctx = canvasContext as CanvasRenderingContext2D; + + const rectWidth = Math.floor(kWidth / 2); + const rectHeight = Math.floor(kHeight / 2); + + // Red + ctx.fillStyle = `rgba(255, 0, 0, 1.0)`; + ctx.fillRect(0, 0, rectWidth, rectHeight); + // Lime + ctx.fillStyle = `rgba(0, 255, 0, 1.0)`; + ctx.fillRect(rectWidth, 0, kWidth - rectWidth, rectHeight); + // Blue + ctx.fillStyle = `rgba(0, 0, 255, 1.0)`; + ctx.fillRect(0, rectHeight, rectWidth, kHeight - rectHeight); + // Fuchsia + ctx.fillStyle = `rgba(255, 0, 255, 1.0)`; + ctx.fillRect(rectWidth, rectHeight, kWidth - rectWidth, kHeight - rectHeight); + + const imageData = ctx.getImageData(0, 0, kWidth, kHeight); + + // Create video frame with default color space 'srgb' + const frameInit: VideoFrameBufferInit = { + format: videoFrameFormat, + codedWidth: kWidth, + codedHeight: kHeight, + timestamp: 0, + }; + + const frame = new VideoFrame(imageData.data.buffer, frameInit); + let textureFormat: GPUTextureFormat = 'rgba8unorm'; + + if (videoFrameFormat === 'BGRA' || videoFrameFormat === 'BGRX') { + textureFormat = 'bgra8unorm'; + } + + const colorAttachment = t.device.createTexture({ + format: textureFormat, + size: { width: kWidth, height: kHeight, depthOrArrayLayers: 1 }, + usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT, + }); + + const pipeline = createExternalTextureSamplingTestPipeline(t, textureFormat); + const bindGroup = createExternalTextureSamplingTestBindGroup( + t, + undefined /* checkNonStandardIsZeroCopy */, + frame, + pipeline, + 'srgb' + ); + + const commandEncoder = t.device.createCommandEncoder(); + const passEncoder = commandEncoder.beginRenderPass({ + colorAttachments: [ + { + view: colorAttachment.createView(), + clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }, + loadOp: 'clear', + storeOp: 'store', + }, + ], + }); + passEncoder.setPipeline(pipeline); + passEncoder.setBindGroup(0, bindGroup); + passEncoder.draw(6); + passEncoder.end(); + t.device.queue.submit([commandEncoder.finish()]); + + const expected = { + topLeft: new Uint8Array([255, 0, 0, 255]), + topRight: new Uint8Array([0, 255, 0, 255]), + bottomLeft: new Uint8Array([0, 0, 255, 255]), + bottomRight: new Uint8Array([255, 0, 255, 255]), + }; + + // For validation, we sample a few pixels away from the edges to avoid compression + // artifacts. + t.expectSinglePixelComparisonsAreOkInTexture({ texture: colorAttachment }, [ + // Top-left. + { + coord: { x: kWidth * 0.25, y: kHeight * 0.25 }, + exp: expected.topLeft, + }, + // Top-right. + { + coord: { x: kWidth * 0.75, y: kHeight * 0.25 }, + exp: expected.topRight, + }, + // Bottom-left. + { + coord: { x: kWidth * 0.25, y: kHeight * 0.75 }, + exp: expected.bottomLeft, + }, + // Bottom-right. + { + coord: { x: kWidth * 0.75, y: kHeight * 0.75 }, + exp: expected.bottomRight, + }, + ]); + }); + g.test('importExternalTexture,sampleWithVideoFrameWithVisibleRectParam') .desc( `