diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 6a616d571a9e..48b019fcf90b 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,110 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "24160909", - "webgpu/shader/execution/binary/af_logical.bin": "ffb5a83f", - "webgpu/shader/execution/binary/af_division.bin": "c230ac78", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "9079a042", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "6b55102f", - "webgpu/shader/execution/binary/af_multiplication.bin": "4fc3b0d6", - "webgpu/shader/execution/binary/af_remainder.bin": "366caec6", - "webgpu/shader/execution/binary/af_subtraction.bin": "49a16db4", - "webgpu/shader/execution/binary/f16_addition.bin": "3fb1ee09", - "webgpu/shader/execution/binary/f16_logical.bin": "65cdc6f", - "webgpu/shader/execution/binary/f16_division.bin": "1b5bd44a", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "fdea291a", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "e727482e", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "24d70bdd", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "7acd3c3b", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "9e01e0cf", - "webgpu/shader/execution/binary/f16_multiplication.bin": "c24b705c", - "webgpu/shader/execution/binary/f16_remainder.bin": "2764c7e1", - "webgpu/shader/execution/binary/f16_subtraction.bin": "d4014a38", - "webgpu/shader/execution/binary/f32_addition.bin": "b6707259", - "webgpu/shader/execution/binary/f32_logical.bin": "d40c1c0", - "webgpu/shader/execution/binary/f32_division.bin": "e19e30a6", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "6a13d6d6", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "4c5cb0a2", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "6b00d17f", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "319d3ae1", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "1c4893ca", - "webgpu/shader/execution/binary/f32_multiplication.bin": "f7dbbc8", - "webgpu/shader/execution/binary/f32_remainder.bin": "fb5dd3fe", - "webgpu/shader/execution/binary/f32_subtraction.bin": "aeaca568", - "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": "2b663377", - "webgpu/shader/execution/acos.bin": "a888c67f", - "webgpu/shader/execution/acosh.bin": "5383658b", - "webgpu/shader/execution/asin.bin": "a580a322", - "webgpu/shader/execution/asinh.bin": "31388535", - "webgpu/shader/execution/atan.bin": "c6f4c771", - "webgpu/shader/execution/atan2.bin": "3b9a37a1", - "webgpu/shader/execution/atanh.bin": "7295a313", - "webgpu/shader/execution/bitcast.bin": "73e0bea6", - "webgpu/shader/execution/ceil.bin": "24bd6be9", - "webgpu/shader/execution/clamp.bin": "8ed55492", - "webgpu/shader/execution/cos.bin": "4d36fa0", - "webgpu/shader/execution/cosh.bin": "a7da3a3", - "webgpu/shader/execution/cross.bin": "6ce2660b", - "webgpu/shader/execution/degrees.bin": "53a0849", - "webgpu/shader/execution/determinant.bin": "873e78af", - "webgpu/shader/execution/distance.bin": "bfce09a0", - "webgpu/shader/execution/dot.bin": "566b6e55", - "webgpu/shader/execution/exp.bin": "d8142d49", - "webgpu/shader/execution/exp2.bin": "52a403d1", - "webgpu/shader/execution/faceForward.bin": "f90dacbe", - "webgpu/shader/execution/floor.bin": "c7465b11", - "webgpu/shader/execution/fma.bin": "db3497d4", - "webgpu/shader/execution/fract.bin": "e65c5bd1", - "webgpu/shader/execution/frexp.bin": "5ce112f4", - "webgpu/shader/execution/inverseSqrt.bin": "84ea0a57", - "webgpu/shader/execution/ldexp.bin": "9d11f120", - "webgpu/shader/execution/length.bin": "dd759736", - "webgpu/shader/execution/log.bin": "5f77a59d", - "webgpu/shader/execution/log2.bin": "57fff45e", - "webgpu/shader/execution/max.bin": "c7cdd54f", - "webgpu/shader/execution/min.bin": "422be325", - "webgpu/shader/execution/mix.bin": "957e7d92", - "webgpu/shader/execution/modf.bin": "946d1f4f", - "webgpu/shader/execution/normalize.bin": "2ac02e80", - "webgpu/shader/execution/pack2x16float.bin": "d7ef3cf5", - "webgpu/shader/execution/pow.bin": "cd492166", - "webgpu/shader/execution/quantizeToF16.bin": "58bac06c", - "webgpu/shader/execution/radians.bin": "6ac08f50", - "webgpu/shader/execution/reflect.bin": "3c260554", - "webgpu/shader/execution/refract.bin": "7e952d7c", - "webgpu/shader/execution/round.bin": "f6b9bda1", - "webgpu/shader/execution/saturate.bin": "1c22f301", - "webgpu/shader/execution/sign.bin": "3ce55105", - "webgpu/shader/execution/sin.bin": "d48e7f2a", - "webgpu/shader/execution/sinh.bin": "f227c1d1", - "webgpu/shader/execution/smoothstep.bin": "6bdb4309", - "webgpu/shader/execution/sqrt.bin": "cd576d27", - "webgpu/shader/execution/step.bin": "dd584686", - "webgpu/shader/execution/tan.bin": "5ae50f61", - "webgpu/shader/execution/tanh.bin": "fe7a619d", - "webgpu/shader/execution/transpose.bin": "469edd7e", - "webgpu/shader/execution/trunc.bin": "8d3a05de", - "webgpu/shader/execution/unpack2x16float.bin": "e897c5ac", - "webgpu/shader/execution/unpack2x16snorm.bin": "450d5402", - "webgpu/shader/execution/unpack2x16unorm.bin": "306b3bf9", - "webgpu/shader/execution/unpack4x8snorm.bin": "fc1bd4c3", - "webgpu/shader/execution/unpack4x8unorm.bin": "763288cc", - "webgpu/shader/execution/unary/af_arithmetic.bin": "a39d4121", - "webgpu/shader/execution/unary/af_assignment.bin": "6ed540e8", - "webgpu/shader/execution/unary/bool_conversion.bin": "f37ea003", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "9cadc739", - "webgpu/shader/execution/unary/f16_conversion.bin": "49c7b38e", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "28da577a", - "webgpu/shader/execution/unary/f32_conversion.bin": "fcdfdd08", - "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": "3fd8797b", - "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "bf99158a", - "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "8bcc7c30" + "webgpu/shader/execution/binary/af_addition.bin": "6a413bb", + "webgpu/shader/execution/binary/af_logical.bin": "aca4ec15", + "webgpu/shader/execution/binary/af_division.bin": "c0c402fb", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "ac02c3cc", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "5cefef99", + "webgpu/shader/execution/binary/af_multiplication.bin": "baf2ecb", + "webgpu/shader/execution/binary/af_remainder.bin": "f8ab0a62", + "webgpu/shader/execution/binary/af_subtraction.bin": "992ca896", + "webgpu/shader/execution/binary/f16_addition.bin": "aadbaf4f", + "webgpu/shader/execution/binary/f16_logical.bin": "d1819e61", + "webgpu/shader/execution/binary/f16_division.bin": "fcc2238", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "f8aa198c", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "a19a43b6", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "404610e9", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "8162896d", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "ec3064be", + "webgpu/shader/execution/binary/f16_multiplication.bin": "caad59d", + "webgpu/shader/execution/binary/f16_remainder.bin": "baa34112", + "webgpu/shader/execution/binary/f16_subtraction.bin": "98f293c", + "webgpu/shader/execution/binary/f32_addition.bin": "ee34bdd1", + "webgpu/shader/execution/binary/f32_logical.bin": "ff534923", + "webgpu/shader/execution/binary/f32_division.bin": "30a8717e", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "18d30aeb", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "f336cee8", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "2cb274df", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "7e3f5b89", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "285e5825", + "webgpu/shader/execution/binary/f32_multiplication.bin": "1278873c", + "webgpu/shader/execution/binary/f32_remainder.bin": "3d552d43", + "webgpu/shader/execution/binary/f32_subtraction.bin": "99143ea1", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "590f5773", + "webgpu/shader/execution/binary/i32_comparison.bin": "30d928c4", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "cf549622", + "webgpu/shader/execution/binary/u32_comparison.bin": "e2195055", + "webgpu/shader/execution/abs.bin": "14f512e7", + "webgpu/shader/execution/acos.bin": "afe306e9", + "webgpu/shader/execution/acosh.bin": "c0c00b36", + "webgpu/shader/execution/asin.bin": "b0456849", + "webgpu/shader/execution/asinh.bin": "93070cea", + "webgpu/shader/execution/atan.bin": "38976d5a", + "webgpu/shader/execution/atan2.bin": "7eb9e897", + "webgpu/shader/execution/atanh.bin": "10a18c44", + "webgpu/shader/execution/bitcast.bin": "e7b49ac0", + "webgpu/shader/execution/ceil.bin": "bbce8194", + "webgpu/shader/execution/clamp.bin": "6539f54e", + "webgpu/shader/execution/cos.bin": "385d43c1", + "webgpu/shader/execution/cosh.bin": "4c077711", + "webgpu/shader/execution/cross.bin": "f71660d0", + "webgpu/shader/execution/degrees.bin": "3542af0b", + "webgpu/shader/execution/determinant.bin": "947f2e95", + "webgpu/shader/execution/distance.bin": "4e747a4b", + "webgpu/shader/execution/dot.bin": "3f593490", + "webgpu/shader/execution/exp.bin": "30ed4c3b", + "webgpu/shader/execution/exp2.bin": "3221e2a4", + "webgpu/shader/execution/faceForward.bin": "c31eb20f", + "webgpu/shader/execution/floor.bin": "fec2987c", + "webgpu/shader/execution/fma.bin": "9190ecb8", + "webgpu/shader/execution/fract.bin": "9ce27b18", + "webgpu/shader/execution/frexp.bin": "bd9ae965", + "webgpu/shader/execution/inverseSqrt.bin": "248cb6b2", + "webgpu/shader/execution/ldexp.bin": "95bf0a9b", + "webgpu/shader/execution/length.bin": "139fd916", + "webgpu/shader/execution/log.bin": "88b6565", + "webgpu/shader/execution/log2.bin": "6e249f91", + "webgpu/shader/execution/max.bin": "49298c6", + "webgpu/shader/execution/min.bin": "706eeb2f", + "webgpu/shader/execution/mix.bin": "69c910ed", + "webgpu/shader/execution/modf.bin": "6063eb0b", + "webgpu/shader/execution/normalize.bin": "e3bbc7df", + "webgpu/shader/execution/pack2x16float.bin": "cc784e85", + "webgpu/shader/execution/pow.bin": "1f5f6a2f", + "webgpu/shader/execution/quantizeToF16.bin": "5e51fe33", + "webgpu/shader/execution/radians.bin": "222586f2", + "webgpu/shader/execution/reflect.bin": "4c3ddd5a", + "webgpu/shader/execution/refract.bin": "35a0b677", + "webgpu/shader/execution/round.bin": "be0524ba", + "webgpu/shader/execution/saturate.bin": "a2a2caec", + "webgpu/shader/execution/sign.bin": "f8871cc5", + "webgpu/shader/execution/sin.bin": "a9c55aeb", + "webgpu/shader/execution/sinh.bin": "5a6dd009", + "webgpu/shader/execution/smoothstep.bin": "2d95dcde", + "webgpu/shader/execution/sqrt.bin": "123bfb33", + "webgpu/shader/execution/step.bin": "aed0a9a3", + "webgpu/shader/execution/tan.bin": "a0fab6d0", + "webgpu/shader/execution/tanh.bin": "a4388aa9", + "webgpu/shader/execution/transpose.bin": "aca7c6f4", + "webgpu/shader/execution/trunc.bin": "de1b4942", + "webgpu/shader/execution/unpack2x16float.bin": "af3af362", + "webgpu/shader/execution/unpack2x16snorm.bin": "433ac579", + "webgpu/shader/execution/unpack2x16unorm.bin": "8b861b88", + "webgpu/shader/execution/unpack4x8snorm.bin": "11d4c569", + "webgpu/shader/execution/unpack4x8unorm.bin": "99130c06", + "webgpu/shader/execution/unary/af_arithmetic.bin": "30e29428", + "webgpu/shader/execution/unary/af_assignment.bin": "e6a967a7", + "webgpu/shader/execution/unary/bool_conversion.bin": "24385996", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "5b3cb5a4", + "webgpu/shader/execution/unary/f16_conversion.bin": "74ceda3", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "85b8d28c", + "webgpu/shader/execution/unary/f32_conversion.bin": "b81c73ab", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "8fe30402", + "webgpu/shader/execution/unary/i32_conversion.bin": "f14993d5", + "webgpu/shader/execution/unary/u32_conversion.bin": "d4426488", + "webgpu/shader/execution/unary/ai_assignment.bin": "755b680", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "925ee615", + "webgpu/shader/execution/unary/ai_arithmetic.bin": "5eec9de1", + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "d5c002e", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "8422517c", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "679f53b1" } \ 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 d3954903ac89..3c24c88e1ffb 100644 Binary files a/src/resources/cache/webgpu/shader/execution/bitcast.bin and b/src/resources/cache/webgpu/shader/execution/bitcast.bin differ diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 6e30934e818c..4c117a904df4 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1934,6 +1934,11 @@ "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,textureSampleBias:array_index_argument:*": { "subcaseMS": 1.630 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleBias:bias_argument:*": { "subcaseMS": 1.102 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleBias:coords_argument:*": { "subcaseMS": 1.938 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleBias:offset_argument,non_const:*": { "subcaseMS": 1.985 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleBias:offset_argument:*": { "subcaseMS": 1.081 }, "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/textureSampleBias.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/textureSampleBias.spec.ts new file mode 100644 index 000000000000..e44f42ce5eb0 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/textureSampleBias.spec.ts @@ -0,0 +1,265 @@ +const builtin = 'textureSampleBias'; +export const description = ` +Validation tests for the ${builtin}() builtin. + +* test textureSampleBias coords parameter must be correct type +* test textureSampleBias array_index parameter must be correct type +* test textureSampleBias bias parameter must be correct type +* test textureSampleBias bias parameter must be between -16.0 and 15.99 inclusive if it's a constant +* test textureSampleBias offset parameter must be correct type +* test textureSampleBias offset parameter must be a const-expression +* test textureSampleBias 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, + acceptsFloat, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +type TextureSampleBiasArguments = { + coordsArgType: ScalarType | VectorType; + hasArrayIndexArg?: boolean; + offsetArgType?: VectorType; +}; + +const isInteger = (v: number) => Math.round(v) === v; + +const kValidTextureSampleBiasParameterTypes: { [n: string]: TextureSampleBiasArguments } = { + '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 }, +} as const; + +const kTextureTypes = keysOf(kValidTextureSampleBiasParameterTypes); +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(kValidTextureSampleBiasParameterTypes)) + .combine('coordType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-1, 0, 1] as const) + .expand('offset', ({ textureType }) => { + const offset = kValidTextureSampleBiasParameterTypes[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, + } = kValidTextureSampleBiasParameterTypes[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 = textureSampleBias(t, s, ${coordWGSL}${arrayWGSL}, 0${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 }) => !!kValidTextureSampleBiasParameterTypes[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 } = kValidTextureSampleBiasParameterTypes[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 = textureSampleBias(t, s, ${coordWGSL}, ${arrayWGSL}, 0${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = + isConvertible(arrayIndexArgType, Type.i32) || isConvertible(arrayIndexArgType, Type.u32); + t.expectCompileResult(expectSuccess, code); + }); + +g.test('bias_argument') + .desc( + ` +Validates that only incorrect bias arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', kTextureTypes) + // filter out types with no offset + .filter( + ({ textureType }) => + kValidTextureSampleBiasParameterTypes[textureType].offsetArgType !== undefined + ) + .combine('biasType', keysOf(kValuesTypes)) + .beginSubcases() + // The spec mentions limits of > -16 and < 15.99 so pass some values around there + // No error is mentioned for out of range values so make sure no error is generated. + .combine('value', [-17, -16, -8, 0, 7, 15.99, 16]) + .filter( + // We can't pass 15.99 to abstractInt.create because BitInt(15.99) throws "not an integer" + ({ biasType, value }) => isInteger(value) || acceptsFloat(kValuesTypes[biasType]) + ) + ) + .fn(t => { + const { textureType, biasType, value } = t.params; + const biasArgType = kValuesTypes[biasType]; + const args = [biasArgType.create(value)]; + const { coordsArgType, hasArrayIndexArg, offsetArgType } = + kValidTextureSampleBiasParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const biasWGSL = 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 = textureSampleBias(t, s, ${coordWGSL}${arrayWGSL}, ${biasWGSL}${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = isConvertible(biasArgType, Type.f32); + 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 }) => + kValidTextureSampleBiasParameterTypes[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, + } = kValidTextureSampleBiasParameterTypes[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 = textureSampleBias(t, s, ${coordWGSL}${arrayWGSL}, 0, ${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 }) => + kValidTextureSampleBiasParameterTypes[textureType].offsetArgType !== undefined + ) + ) + .fn(t => { + const { textureType, varType } = t.params; + const { coordsArgType, hasArrayIndexArg, offsetArgType } = + kValidTextureSampleBiasParameterTypes[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 = textureSampleBias(t, s, ${coordWGSL}${arrayWGSL}, 0, ${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 4925899811b5..0869f931ef63 100644 --- a/src/webgpu/util/conversion.ts +++ b/src/webgpu/util/conversion.ts @@ -2234,6 +2234,18 @@ export function isFloatType(ty: Type): boolean { return false; } +/** + * @returns if `ty ` accepts a floating point value. abstract-int does not because it uses BigInt + * and throws if passed a non integer value. + */ +export function acceptsFloat(ty: Type): boolean { + if (ty instanceof ScalarType) { + return ty.kind !== 'abstract-int'; + } else { + return acceptsFloat(ty.elementType); + } +} + /** @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) {