From 0771e27eff930099af8484f185825fb44cae2963 Mon Sep 17 00:00:00 2001 From: Greggman Date: Wed, 13 Mar 2024 09:50:41 +0900 Subject: [PATCH] Test `textureSample` WGSL validation (#3478) * Test `textureSample` WGSL validation --- src/resources/cache/hashes.json | 216 ++++++++--------- .../cache/webgpu/shader/execution/bitcast.bin | Bin 2221448 -> 2221448 bytes src/webgpu/listing_meta.json | 4 + .../call/builtin/textureSample.spec.ts | 218 ++++++++++++++++++ src/webgpu/util/conversion.ts | 50 ++++ 5 files changed, 380 insertions(+), 108 deletions(-) create mode 100644 src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 9692310ae56e..db69ef779b10 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,110 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "f93f6f2", - "webgpu/shader/execution/binary/af_logical.bin": "412fdd40", - "webgpu/shader/execution/binary/af_division.bin": "7b359c01", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "ad3e51de", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "10ae4166", - "webgpu/shader/execution/binary/af_multiplication.bin": "f3eb97ee", - "webgpu/shader/execution/binary/af_remainder.bin": "1c08510d", - "webgpu/shader/execution/binary/af_subtraction.bin": "1ea78ded", - "webgpu/shader/execution/binary/f16_addition.bin": "97c6c220", - "webgpu/shader/execution/binary/f16_logical.bin": "2d07c65d", - "webgpu/shader/execution/binary/f16_division.bin": "fd11268e", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "6e8f752c", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "ebfe95b8", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "21577c69", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "ca569737", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "8d7a02b5", - "webgpu/shader/execution/binary/f16_multiplication.bin": "aee2b921", - "webgpu/shader/execution/binary/f16_remainder.bin": "f9397246", - "webgpu/shader/execution/binary/f16_subtraction.bin": "8f80b4b4", - "webgpu/shader/execution/binary/f32_addition.bin": "3b09cfd7", - "webgpu/shader/execution/binary/f32_logical.bin": "ab23c69a", - "webgpu/shader/execution/binary/f32_division.bin": "2e8d775b", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "7276a303", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "26789d70", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "beb34505", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "1b426bf8", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "ee372ef3", - "webgpu/shader/execution/binary/f32_multiplication.bin": "a58fb275", - "webgpu/shader/execution/binary/f32_remainder.bin": "4fca1678", - "webgpu/shader/execution/binary/f32_subtraction.bin": "a77fcae2", - "webgpu/shader/execution/binary/i32_arithmetic.bin": "483b584e", - "webgpu/shader/execution/binary/i32_comparison.bin": "a1310d6d", - "webgpu/shader/execution/binary/u32_arithmetic.bin": "4ed255b", - "webgpu/shader/execution/binary/u32_comparison.bin": "2766735c", - "webgpu/shader/execution/abs.bin": "74007d00", - "webgpu/shader/execution/acos.bin": "71afa785", - "webgpu/shader/execution/acosh.bin": "7eb972b3", - "webgpu/shader/execution/asin.bin": "cf1f15dc", - "webgpu/shader/execution/asinh.bin": "77d8090c", - "webgpu/shader/execution/atan.bin": "f984effa", - "webgpu/shader/execution/atan2.bin": "f71eeef0", - "webgpu/shader/execution/atanh.bin": "f70ef8f3", - "webgpu/shader/execution/bitcast.bin": "61596841", - "webgpu/shader/execution/ceil.bin": "d3912020", - "webgpu/shader/execution/clamp.bin": "3af7b577", - "webgpu/shader/execution/cos.bin": "a1b9931a", - "webgpu/shader/execution/cosh.bin": "9d4816da", - "webgpu/shader/execution/cross.bin": "75ee9e89", - "webgpu/shader/execution/degrees.bin": "1c88f619", - "webgpu/shader/execution/determinant.bin": "16acfafa", - "webgpu/shader/execution/distance.bin": "1098d127", - "webgpu/shader/execution/dot.bin": "e1a8d3bc", - "webgpu/shader/execution/exp.bin": "cdb0e2b9", - "webgpu/shader/execution/exp2.bin": "665ec45a", - "webgpu/shader/execution/faceForward.bin": "f22e0c0a", - "webgpu/shader/execution/floor.bin": "ede6258", - "webgpu/shader/execution/fma.bin": "34c7474", - "webgpu/shader/execution/fract.bin": "3e0d009a", - "webgpu/shader/execution/frexp.bin": "23465618", - "webgpu/shader/execution/inverseSqrt.bin": "487cf433", - "webgpu/shader/execution/ldexp.bin": "20d14a1", - "webgpu/shader/execution/length.bin": "95b9dd44", - "webgpu/shader/execution/log.bin": "13bdb23", - "webgpu/shader/execution/log2.bin": "3a5cbd55", - "webgpu/shader/execution/max.bin": "7e1f71fc", - "webgpu/shader/execution/min.bin": "6dc2bb2d", - "webgpu/shader/execution/mix.bin": "d019504f", - "webgpu/shader/execution/modf.bin": "8f3f56ec", - "webgpu/shader/execution/normalize.bin": "480fa5d8", - "webgpu/shader/execution/pack2x16float.bin": "1d32fd43", - "webgpu/shader/execution/pow.bin": "992dd6fd", - "webgpu/shader/execution/quantizeToF16.bin": "457045cb", - "webgpu/shader/execution/radians.bin": "4660460e", - "webgpu/shader/execution/reflect.bin": "d49b4a70", - "webgpu/shader/execution/refract.bin": "81d973ab", - "webgpu/shader/execution/round.bin": "a9617b62", - "webgpu/shader/execution/saturate.bin": "8616be85", - "webgpu/shader/execution/sign.bin": "4747c867", - "webgpu/shader/execution/sin.bin": "b60c310f", - "webgpu/shader/execution/sinh.bin": "8c24825e", - "webgpu/shader/execution/smoothstep.bin": "c5730ac6", - "webgpu/shader/execution/sqrt.bin": "44d4bf9b", - "webgpu/shader/execution/step.bin": "183935c1", - "webgpu/shader/execution/tan.bin": "5c8ab74a", - "webgpu/shader/execution/tanh.bin": "f233ceba", - "webgpu/shader/execution/transpose.bin": "86a6b61c", - "webgpu/shader/execution/trunc.bin": "7f07d161", - "webgpu/shader/execution/unpack2x16float.bin": "cfe367ce", - "webgpu/shader/execution/unpack2x16snorm.bin": "fcfe4174", - "webgpu/shader/execution/unpack2x16unorm.bin": "f419844a", - "webgpu/shader/execution/unpack4x8snorm.bin": "c3343320", - "webgpu/shader/execution/unpack4x8unorm.bin": "24618d08", - "webgpu/shader/execution/unary/af_arithmetic.bin": "ae3cf04d", - "webgpu/shader/execution/unary/af_assignment.bin": "823b0b98", - "webgpu/shader/execution/unary/bool_conversion.bin": "25551e87", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "b1604cf7", - "webgpu/shader/execution/unary/f16_conversion.bin": "6c9e1961", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "13fc8cf0", - "webgpu/shader/execution/unary/f32_conversion.bin": "3a4e8649", - "webgpu/shader/execution/unary/i32_arithmetic.bin": "ca6bdc9e", - "webgpu/shader/execution/unary/i32_conversion.bin": "44881769", - "webgpu/shader/execution/unary/u32_conversion.bin": "535edb49", - "webgpu/shader/execution/unary/ai_assignment.bin": "607105c7", - "webgpu/shader/execution/binary/ai_arithmetic.bin": "5718501b", - "webgpu/shader/execution/unary/ai_arithmetic.bin": "9aff9753", - "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "c24c52ce", - "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "7df31c69", - "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "eb2e28a" + "webgpu/shader/execution/binary/af_addition.bin": "91af48f0", + "webgpu/shader/execution/binary/af_logical.bin": "ffb5a83f", + "webgpu/shader/execution/binary/af_division.bin": "73039eea", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "e13e9e6e", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "5dc56318", + "webgpu/shader/execution/binary/af_multiplication.bin": "33cb4a90", + "webgpu/shader/execution/binary/af_remainder.bin": "b06c2cd5", + "webgpu/shader/execution/binary/af_subtraction.bin": "d5c5a9de", + "webgpu/shader/execution/binary/f16_addition.bin": "41c253b", + "webgpu/shader/execution/binary/f16_logical.bin": "65cdc6f", + "webgpu/shader/execution/binary/f16_division.bin": "4e0dd3f3", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "7131d2e", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "27105bab", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "e4edd8d1", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "3f8f0d6", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "4379fdb1", + "webgpu/shader/execution/binary/f16_multiplication.bin": "f1ce631d", + "webgpu/shader/execution/binary/f16_remainder.bin": "c3400825", + "webgpu/shader/execution/binary/f16_subtraction.bin": "c84c09b4", + "webgpu/shader/execution/binary/f32_addition.bin": "d1ce98cf", + "webgpu/shader/execution/binary/f32_logical.bin": "d40c1c0", + "webgpu/shader/execution/binary/f32_division.bin": "27a33c63", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "84296a9c", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "a601448a", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "f025741a", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "db1d203c", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "a7456950", + "webgpu/shader/execution/binary/f32_multiplication.bin": "e6a47586", + "webgpu/shader/execution/binary/f32_remainder.bin": "31d588d", + "webgpu/shader/execution/binary/f32_subtraction.bin": "4b79931f", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "90a3514a", + "webgpu/shader/execution/binary/i32_comparison.bin": "840b09e6", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "e3f04e97", + "webgpu/shader/execution/binary/u32_comparison.bin": "dc1398d3", + "webgpu/shader/execution/abs.bin": "1ff1f454", + "webgpu/shader/execution/acos.bin": "539c5984", + "webgpu/shader/execution/acosh.bin": "e1155c5f", + "webgpu/shader/execution/asin.bin": "a17f7afb", + "webgpu/shader/execution/asinh.bin": "dbb0f8a", + "webgpu/shader/execution/atan.bin": "80b2e232", + "webgpu/shader/execution/atan2.bin": "19853e04", + "webgpu/shader/execution/atanh.bin": "1dd56fe0", + "webgpu/shader/execution/bitcast.bin": "83ba0a2d", + "webgpu/shader/execution/ceil.bin": "51abcdee", + "webgpu/shader/execution/clamp.bin": "8b77f1be", + "webgpu/shader/execution/cos.bin": "486fa019", + "webgpu/shader/execution/cosh.bin": "b796f446", + "webgpu/shader/execution/cross.bin": "934a9528", + "webgpu/shader/execution/degrees.bin": "e767ec2b", + "webgpu/shader/execution/determinant.bin": "a82df7ed", + "webgpu/shader/execution/distance.bin": "189f7e7", + "webgpu/shader/execution/dot.bin": "48b08425", + "webgpu/shader/execution/exp.bin": "7a9b65c9", + "webgpu/shader/execution/exp2.bin": "40857179", + "webgpu/shader/execution/faceForward.bin": "a4d3d7fd", + "webgpu/shader/execution/floor.bin": "78ddd3e0", + "webgpu/shader/execution/fma.bin": "8fe936c7", + "webgpu/shader/execution/fract.bin": "c9527ef2", + "webgpu/shader/execution/frexp.bin": "66d03941", + "webgpu/shader/execution/inverseSqrt.bin": "b6242d36", + "webgpu/shader/execution/ldexp.bin": "a0827b94", + "webgpu/shader/execution/length.bin": "23579568", + "webgpu/shader/execution/log.bin": "43822075", + "webgpu/shader/execution/log2.bin": "18e01bd3", + "webgpu/shader/execution/max.bin": "3754c33c", + "webgpu/shader/execution/min.bin": "33935035", + "webgpu/shader/execution/mix.bin": "f67ad46a", + "webgpu/shader/execution/modf.bin": "edb80b8c", + "webgpu/shader/execution/normalize.bin": "167d7c79", + "webgpu/shader/execution/pack2x16float.bin": "d7ef3cf5", + "webgpu/shader/execution/pow.bin": "b3f33461", + "webgpu/shader/execution/quantizeToF16.bin": "c41ec650", + "webgpu/shader/execution/radians.bin": "74748445", + "webgpu/shader/execution/reflect.bin": "e2b029bd", + "webgpu/shader/execution/refract.bin": "7916ffc2", + "webgpu/shader/execution/round.bin": "8d428840", + "webgpu/shader/execution/saturate.bin": "6de2e522", + "webgpu/shader/execution/sign.bin": "7ae6222a", + "webgpu/shader/execution/sin.bin": "4178e4ca", + "webgpu/shader/execution/sinh.bin": "7c104d99", + "webgpu/shader/execution/smoothstep.bin": "c461cdc6", + "webgpu/shader/execution/sqrt.bin": "bf85c8fb", + "webgpu/shader/execution/step.bin": "adb873a1", + "webgpu/shader/execution/tan.bin": "a1777146", + "webgpu/shader/execution/tanh.bin": "ceeebb22", + "webgpu/shader/execution/transpose.bin": "f41b25c8", + "webgpu/shader/execution/trunc.bin": "c71488f3", + "webgpu/shader/execution/unpack2x16float.bin": "a763e4a1", + "webgpu/shader/execution/unpack2x16snorm.bin": "e414f14b", + "webgpu/shader/execution/unpack2x16unorm.bin": "488b474a", + "webgpu/shader/execution/unpack4x8snorm.bin": "d4fd9078", + "webgpu/shader/execution/unpack4x8unorm.bin": "7aa3c88e", + "webgpu/shader/execution/unary/af_arithmetic.bin": "14207fe0", + "webgpu/shader/execution/unary/af_assignment.bin": "ddb98d17", + "webgpu/shader/execution/unary/bool_conversion.bin": "f37ea003", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "26b20f68", + "webgpu/shader/execution/unary/f16_conversion.bin": "5e3a4bce", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "c30910", + "webgpu/shader/execution/unary/f32_conversion.bin": "7e716fd3", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "25cf27d1", + "webgpu/shader/execution/unary/i32_conversion.bin": "276dcf69", + "webgpu/shader/execution/unary/u32_conversion.bin": "acac2172", + "webgpu/shader/execution/unary/ai_assignment.bin": "c876d431", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "36a1d65b", + "webgpu/shader/execution/unary/ai_arithmetic.bin": "89e34dcf", + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "4116ac44", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "b2738fb2", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "4d3df8a8" } \ No newline at end of file diff --git a/src/resources/cache/webgpu/shader/execution/bitcast.bin b/src/resources/cache/webgpu/shader/execution/bitcast.bin index d3954903ac89afcfbe5049a356005ed02cf10aae..3c24c88e1ffbc42f87639912bacab411154e6d63 100644 GIT binary patch delta 151 zcmWN=M-6~L006yPYE?jRVw)gr0)tx&a delta 152 zcmWN=%MpSw6hP4l3d%o-f*(*Rf!897WKSO%h7G$EpiObl%&~u?EEgxU8};PHcu@>^ r;E^FCo_J==gef!TELc*r;)OM@ys=@+J0E=V#g0AS{P4SZ8Gh>y9V9$( diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 2db6cc8785dd..f5e899581b47 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1928,6 +1928,10 @@ "webgpu:shader,validation,expression,call,builtin,sqrt:values:*": { "subcaseMS": 0.302 }, "webgpu:shader,validation,expression,call,builtin,tan:integer_argument:*": { "subcaseMS": 1.734 }, "webgpu:shader,validation,expression,call,builtin,tan:values:*": { "subcaseMS": 0.350 }, + "webgpu:shader,validation,expression,call,builtin,textureSample:array_index_argument:*": { "subcaseMS": 1.888 }, + "webgpu:shader,validation,expression,call,builtin,textureSample:coords_argument:*": { "subcaseMS": 1.342 }, + "webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument,non_const:*": { "subcaseMS": 1.604 }, + "webgpu:shader,validation,expression,call,builtin,textureSample:offset_argument:*": { "subcaseMS": 1.401 }, "webgpu:shader,validation,expression,call,builtin,unpack4xI8:bad_args:*": { "subcaseMS": 121.263 }, "webgpu:shader,validation,expression,call,builtin,unpack4xI8:must_use:*": { "subcaseMS": 35.200 }, "webgpu:shader,validation,expression,call,builtin,unpack4xI8:supported:*": { "subcaseMS": 24.150 }, diff --git a/src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts new file mode 100644 index 000000000000..0d63c059d719 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts @@ -0,0 +1,218 @@ +const builtin = 'textureSample'; +export const description = ` +Validation tests for the ${builtin}() builtin. + +* test textureSample coords parameter must be correct type +* test textureSample array_index parameter must be correct type +* test textureSample coords parameter must be correct type +* test textureSample offset parameter must be correct type +* test textureSample offset parameter must be a const-expression +* test textureSample offset parameter must be between -8 and +7 inclusive +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; +import { + Type, + kAllScalarsAndVectors, + isConvertible, + ScalarType, + VectorType, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +type TextureSampleArguments = { + coordsArgType: ScalarType | VectorType; + hasArrayIndexArg?: boolean; + offsetArgType?: VectorType; +}; + +const kValidTextureSampleParameterTypes: { [n: string]: TextureSampleArguments } = { + 'texture_1d': { coordsArgType: Type.f32 }, + 'texture_2d': { coordsArgType: Type.vec2f, offsetArgType: Type.vec2i }, + 'texture_2d_array': { + coordsArgType: Type.vec2f, + hasArrayIndexArg: true, + offsetArgType: Type.vec2i, + }, + 'texture_3d': { coordsArgType: Type.vec3f, offsetArgType: Type.vec3i }, + 'texture_cube': { coordsArgType: Type.vec3f }, + 'texture_cube_array': { coordsArgType: Type.vec3f, hasArrayIndexArg: true }, + texture_depth_2d: { coordsArgType: Type.vec2f, offsetArgType: Type.vec2i }, + texture_depth_2d_array: { coordsArgType: Type.vec2f, hasArrayIndexArg: true }, + texture_depth_cube: { coordsArgType: Type.vec3f }, + texture_depth_cube_array: { coordsArgType: Type.vec3f, hasArrayIndexArg: true }, +} as const; + +const kTextureTypes = keysOf(kValidTextureSampleParameterTypes); +const kValuesTypes = objectsToRecord(kAllScalarsAndVectors); + +export const g = makeTestGroup(ShaderValidationTest); + +g.test('coords_argument') + .desc( + ` +Validates that only incorrect coords arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', keysOf(kValidTextureSampleParameterTypes)) + .combine('coordType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-1, 0, 1] as const) + .expand('offset', ({ textureType }) => { + const offset = kValidTextureSampleParameterTypes[textureType].offsetArgType; + return offset ? [false, true] : [false]; + }) + ) + .fn(t => { + const { textureType, coordType, offset, value } = t.params; + const coordArgType = kValuesTypes[coordType]; + const { + offsetArgType, + coordsArgType: coordsRequiredType, + hasArrayIndexArg, + } = kValidTextureSampleParameterTypes[textureType]; + + const coordWGSL = coordArgType.create(value).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const offsetWGSL = offset ? `, ${offsetArgType?.create(0).wgsl()}` : ''; + + const code = ` +@group(0) @binding(0) var s: sampler; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSample(t, s, ${coordWGSL}${arrayWGSL}${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = isConvertible(coordArgType, coordsRequiredType); + t.expectCompileResult(expectSuccess, code); + }); + +g.test('array_index_argument') + .desc( + ` +Validates that only incorrect array_index arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', kTextureTypes) + // filter out types with no array_index + .filter( + ({ textureType }) => !!kValidTextureSampleParameterTypes[textureType].hasArrayIndexArg + ) + .combine('arrayIndexType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-9, -8, 0, 7, 8]) + ) + .fn(t => { + const { textureType, arrayIndexType, value } = t.params; + const arrayIndexArgType = kValuesTypes[arrayIndexType]; + const args = [arrayIndexArgType.create(value)]; + const { coordsArgType, offsetArgType } = kValidTextureSampleParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = args.map(arg => arg.wgsl()).join(', '); + const offsetWGSL = offsetArgType ? `, ${offsetArgType.create(0).wgsl()}` : ''; + + const code = ` +@group(0) @binding(0) var s: sampler; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSample(t, s, ${coordWGSL}, ${arrayWGSL}${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = + isConvertible(arrayIndexArgType, Type.i32) || isConvertible(arrayIndexArgType, Type.u32); + t.expectCompileResult(expectSuccess, code); + }); + +g.test('offset_argument') + .desc( + ` +Validates that only incorrect offset arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', kTextureTypes) + // filter out types with no offset + .filter( + ({ textureType }) => + kValidTextureSampleParameterTypes[textureType].offsetArgType !== undefined + ) + .combine('offsetType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-9, -8, 0, 7, 8]) + ) + .fn(t => { + const { textureType, offsetType, value } = t.params; + const offsetArgType = kValuesTypes[offsetType]; + const args = [offsetArgType.create(value)]; + const { + coordsArgType, + hasArrayIndexArg, + offsetArgType: offsetRequiredType, + } = kValidTextureSampleParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const offsetWGSL = args.map(arg => arg.wgsl()).join(', '); + + const code = ` +@group(0) @binding(0) var s: sampler; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSample(t, s, ${coordWGSL}${arrayWGSL}, ${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = + isConvertible(offsetArgType, offsetRequiredType!) && value >= -8 && value <= 7; + t.expectCompileResult(expectSuccess, code); + }); + +g.test('offset_argument,non_const') + .desc( + ` +Validates that only non-const offset arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', kTextureTypes) + .combine('varType', ['c', 'u', 'l']) + // filter out types with no offset + .filter( + ({ textureType }) => + kValidTextureSampleParameterTypes[textureType].offsetArgType !== undefined + ) + ) + .fn(t => { + const { textureType, varType } = t.params; + const { coordsArgType, hasArrayIndexArg, offsetArgType } = + kValidTextureSampleParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const offsetWGSL = `${offsetArgType}(${varType})`; + const castWGSL = offsetArgType!.elementType.toString(); + + const code = ` +@group(0) @binding(0) var s: sampler; +@group(0) @binding(1) var t: ${textureType}; +@group(0) @binding(2) var u: ${offsetArgType}; +@fragment fn fs(@builtin(position) p: vec4f) -> @location(0) vec4f { + const c = 1; + let l = ${offsetArgType}(${castWGSL}(p.x)); + let v = textureSample(t, s, ${coordWGSL}${arrayWGSL}, ${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = varType === 'c'; + t.expectCompileResult(expectSuccess, code); + }); diff --git a/src/webgpu/util/conversion.ts b/src/webgpu/util/conversion.ts index 15557b3d4c57..4925899811b5 100644 --- a/src/webgpu/util/conversion.ts +++ b/src/webgpu/util/conversion.ts @@ -2234,6 +2234,56 @@ export function isFloatType(ty: Type): boolean { return false; } +/** @returns true if an argument of type 'src' can be used for a parameter of type 'dst' */ +export function isConvertible(src: Type, dst: Type) { + if (src === dst) { + return true; + } + + const widthOf = (ty: Type) => { + return ty instanceof VectorType ? ty.width : 1; + }; + + if (widthOf(src) !== widthOf(dst)) { + return false; + } + + const elSrc = scalarTypeOf(src); + const elDst = scalarTypeOf(dst); + + switch (elSrc.kind) { + case 'abstract-float': + switch (elDst.kind) { + case 'abstract-float': + case 'f16': + case 'f32': + case 'f64': + return true; + default: + return false; + } + case 'abstract-int': + switch (elDst.kind) { + case 'abstract-int': + case 'abstract-float': + case 'f16': + case 'f32': + case 'f64': + case 'u16': + case 'u32': + case 'u8': + case 'i16': + case 'i32': + case 'i8': + return true; + default: + return false; + } + default: + return false; + } +} + /// All floating-point scalar types const kFloatScalars = [Type.abstractFloat, Type.f32, Type.f16] as const;