From 745364412a51ccdb6a9f373e9b778abcb4e73451 Mon Sep 17 00:00:00 2001 From: Greggman Date: Fri, 15 Mar 2024 03:22:53 +0900 Subject: [PATCH] WGSL Validation tests for textureSampleCompare (#3500) * WGSL Validation tests for textureSampleCompare --- src/resources/cache/hashes.json | 216 +++++++-------- .../cache/webgpu/shader/execution/bitcast.bin | Bin 2221448 -> 2221448 bytes src/webgpu/listing_meta.json | 5 + .../call/builtin/textureSample.spec.ts | 32 +-- .../call/builtin/textureSampleCompare.spec.ts | 249 ++++++++++++++++++ src/webgpu/util/conversion.ts | 11 + 6 files changed, 390 insertions(+), 123 deletions(-) create mode 100644 src/webgpu/shader/validation/expression/call/builtin/textureSampleCompare.spec.ts diff --git a/src/resources/cache/hashes.json b/src/resources/cache/hashes.json index 1bbb980a95fc..c047bf04cbab 100644 --- a/src/resources/cache/hashes.json +++ b/src/resources/cache/hashes.json @@ -1,110 +1,110 @@ { - "webgpu/shader/execution/binary/af_addition.bin": "2607cb36", - "webgpu/shader/execution/binary/af_logical.bin": "ffb5a83f", - "webgpu/shader/execution/binary/af_division.bin": "9642be53", - "webgpu/shader/execution/binary/af_matrix_addition.bin": "28783339", - "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "fd58a70a", - "webgpu/shader/execution/binary/af_multiplication.bin": "48fb6954", - "webgpu/shader/execution/binary/af_remainder.bin": "31290507", - "webgpu/shader/execution/binary/af_subtraction.bin": "aa7a977f", - "webgpu/shader/execution/binary/f16_addition.bin": "8dee9967", - "webgpu/shader/execution/binary/f16_logical.bin": "65cdc6f", - "webgpu/shader/execution/binary/f16_division.bin": "7642d7e5", - "webgpu/shader/execution/binary/f16_matrix_addition.bin": "451a2ca2", - "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "1a730f23", - "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "4e59085f", - "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "831ef7d9", - "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "9956e198", - "webgpu/shader/execution/binary/f16_multiplication.bin": "f0593e54", - "webgpu/shader/execution/binary/f16_remainder.bin": "390d16d7", - "webgpu/shader/execution/binary/f16_subtraction.bin": "89d5e800", - "webgpu/shader/execution/binary/f32_addition.bin": "204ae10f", - "webgpu/shader/execution/binary/f32_logical.bin": "d40c1c0", - "webgpu/shader/execution/binary/f32_division.bin": "38119537", - "webgpu/shader/execution/binary/f32_matrix_addition.bin": "ee4f7b76", - "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "1145eefd", - "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "9b0de895", - "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "a1caf103", - "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "63b9f583", - "webgpu/shader/execution/binary/f32_multiplication.bin": "8c039186", - "webgpu/shader/execution/binary/f32_remainder.bin": "7d54ad97", - "webgpu/shader/execution/binary/f32_subtraction.bin": "9080f361", - "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": "cbc5bb84", - "webgpu/shader/execution/acos.bin": "99826c48", - "webgpu/shader/execution/acosh.bin": "86faac44", - "webgpu/shader/execution/asin.bin": "1aa47c31", - "webgpu/shader/execution/asinh.bin": "3ca77d23", - "webgpu/shader/execution/atan.bin": "f3b4fad4", - "webgpu/shader/execution/atan2.bin": "695628c1", - "webgpu/shader/execution/atanh.bin": "ccac869a", - "webgpu/shader/execution/bitcast.bin": "a46c0f3c", - "webgpu/shader/execution/ceil.bin": "15ea076", - "webgpu/shader/execution/clamp.bin": "16a6107", - "webgpu/shader/execution/cos.bin": "8608aa24", - "webgpu/shader/execution/cosh.bin": "406887b3", - "webgpu/shader/execution/cross.bin": "ef98a37f", - "webgpu/shader/execution/degrees.bin": "a1f81fe8", - "webgpu/shader/execution/determinant.bin": "925aced0", - "webgpu/shader/execution/distance.bin": "1d1daa4b", - "webgpu/shader/execution/dot.bin": "5e618a78", - "webgpu/shader/execution/exp.bin": "c9ff3ee4", - "webgpu/shader/execution/exp2.bin": "124dd7fa", - "webgpu/shader/execution/faceForward.bin": "766871a0", - "webgpu/shader/execution/floor.bin": "bdbcec65", - "webgpu/shader/execution/fma.bin": "df9710d4", - "webgpu/shader/execution/fract.bin": "c6ac37ac", - "webgpu/shader/execution/frexp.bin": "4e41a6ad", - "webgpu/shader/execution/inverseSqrt.bin": "a874b8e0", - "webgpu/shader/execution/ldexp.bin": "52e686eb", - "webgpu/shader/execution/length.bin": "864e5694", - "webgpu/shader/execution/log.bin": "d86b6b5e", - "webgpu/shader/execution/log2.bin": "bb5ba2bc", - "webgpu/shader/execution/max.bin": "3e73f492", - "webgpu/shader/execution/min.bin": "6cc26be0", - "webgpu/shader/execution/mix.bin": "aca1fe65", - "webgpu/shader/execution/modf.bin": "e8dc88c2", - "webgpu/shader/execution/normalize.bin": "bd40a69", - "webgpu/shader/execution/pack2x16float.bin": "d7ef3cf5", - "webgpu/shader/execution/pow.bin": "a3f1d7bc", - "webgpu/shader/execution/quantizeToF16.bin": "cc9b060d", - "webgpu/shader/execution/radians.bin": "a4a45624", - "webgpu/shader/execution/reflect.bin": "f0edf7b6", - "webgpu/shader/execution/refract.bin": "b45fa1e3", - "webgpu/shader/execution/round.bin": "98a6ca02", - "webgpu/shader/execution/saturate.bin": "1724df20", - "webgpu/shader/execution/sign.bin": "c9304bbc", - "webgpu/shader/execution/sin.bin": "101ac9b0", - "webgpu/shader/execution/sinh.bin": "339cfa9d", - "webgpu/shader/execution/smoothstep.bin": "bd0ee34b", - "webgpu/shader/execution/sqrt.bin": "33a74294", - "webgpu/shader/execution/step.bin": "a546d1c7", - "webgpu/shader/execution/tan.bin": "98495e6c", - "webgpu/shader/execution/tanh.bin": "c8abf523", - "webgpu/shader/execution/transpose.bin": "48b9967b", - "webgpu/shader/execution/trunc.bin": "111d452f", - "webgpu/shader/execution/unpack2x16float.bin": "cafe4182", - "webgpu/shader/execution/unpack2x16snorm.bin": "9025c24a", - "webgpu/shader/execution/unpack2x16unorm.bin": "edec162d", - "webgpu/shader/execution/unpack4x8snorm.bin": "89fc1230", - "webgpu/shader/execution/unpack4x8unorm.bin": "6016b1d8", - "webgpu/shader/execution/unary/af_arithmetic.bin": "9f02dd09", - "webgpu/shader/execution/unary/af_assignment.bin": "2a53eabc", - "webgpu/shader/execution/unary/bool_conversion.bin": "f37ea003", - "webgpu/shader/execution/unary/f16_arithmetic.bin": "5596e63b", - "webgpu/shader/execution/unary/f16_conversion.bin": "ae15a286", - "webgpu/shader/execution/unary/f32_arithmetic.bin": "1b8dfc4a", - "webgpu/shader/execution/unary/f32_conversion.bin": "3d408f29", - "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": "c6bc506b", - "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "a77a12e3", - "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "fb71513a" + "webgpu/shader/execution/binary/af_addition.bin": "356a2727", + "webgpu/shader/execution/binary/af_logical.bin": "ebab5627", + "webgpu/shader/execution/binary/af_division.bin": "21c09759", + "webgpu/shader/execution/binary/af_matrix_addition.bin": "e757d879", + "webgpu/shader/execution/binary/af_matrix_subtraction.bin": "ea02f769", + "webgpu/shader/execution/binary/af_multiplication.bin": "bfdeef2b", + "webgpu/shader/execution/binary/af_remainder.bin": "d321f31", + "webgpu/shader/execution/binary/af_subtraction.bin": "435e1e2a", + "webgpu/shader/execution/binary/f16_addition.bin": "5cf85e53", + "webgpu/shader/execution/binary/f16_logical.bin": "7ffeb775", + "webgpu/shader/execution/binary/f16_division.bin": "7035ad6b", + "webgpu/shader/execution/binary/f16_matrix_addition.bin": "ba974e19", + "webgpu/shader/execution/binary/f16_matrix_matrix_multiplication.bin": "fd8da1c", + "webgpu/shader/execution/binary/f16_matrix_scalar_multiplication.bin": "790b592a", + "webgpu/shader/execution/binary/f16_matrix_subtraction.bin": "32688cc0", + "webgpu/shader/execution/binary/f16_matrix_vector_multiplication.bin": "55ffb99c", + "webgpu/shader/execution/binary/f16_multiplication.bin": "ef13265a", + "webgpu/shader/execution/binary/f16_remainder.bin": "49f9c6df", + "webgpu/shader/execution/binary/f16_subtraction.bin": "948133b7", + "webgpu/shader/execution/binary/f32_addition.bin": "b35cc0d", + "webgpu/shader/execution/binary/f32_logical.bin": "7577fe3", + "webgpu/shader/execution/binary/f32_division.bin": "ab118f7", + "webgpu/shader/execution/binary/f32_matrix_addition.bin": "a672d927", + "webgpu/shader/execution/binary/f32_matrix_matrix_multiplication.bin": "9b703409", + "webgpu/shader/execution/binary/f32_matrix_scalar_multiplication.bin": "5049bd07", + "webgpu/shader/execution/binary/f32_matrix_subtraction.bin": "64a4374", + "webgpu/shader/execution/binary/f32_matrix_vector_multiplication.bin": "163c8aa9", + "webgpu/shader/execution/binary/f32_multiplication.bin": "2d544b2d", + "webgpu/shader/execution/binary/f32_remainder.bin": "49a1d8ae", + "webgpu/shader/execution/binary/f32_subtraction.bin": "867fb863", + "webgpu/shader/execution/binary/i32_arithmetic.bin": "1229d4e0", + "webgpu/shader/execution/binary/i32_comparison.bin": "e434ac4c", + "webgpu/shader/execution/binary/u32_arithmetic.bin": "a32e45a1", + "webgpu/shader/execution/binary/u32_comparison.bin": "83555cf6", + "webgpu/shader/execution/abs.bin": "c641f057", + "webgpu/shader/execution/acos.bin": "6f3d5a7e", + "webgpu/shader/execution/acosh.bin": "3a43c03a", + "webgpu/shader/execution/asin.bin": "479587b0", + "webgpu/shader/execution/asinh.bin": "16e1db15", + "webgpu/shader/execution/atan.bin": "8f66f0c3", + "webgpu/shader/execution/atan2.bin": "daf31851", + "webgpu/shader/execution/atanh.bin": "9ea23353", + "webgpu/shader/execution/bitcast.bin": "4791d08a", + "webgpu/shader/execution/ceil.bin": "d6f9f851", + "webgpu/shader/execution/clamp.bin": "32c98572", + "webgpu/shader/execution/cos.bin": "d7131516", + "webgpu/shader/execution/cosh.bin": "ab780f6", + "webgpu/shader/execution/cross.bin": "6ad5ba88", + "webgpu/shader/execution/degrees.bin": "168cb418", + "webgpu/shader/execution/determinant.bin": "9a310a55", + "webgpu/shader/execution/distance.bin": "ebd22afe", + "webgpu/shader/execution/dot.bin": "d31296bd", + "webgpu/shader/execution/exp.bin": "986179cb", + "webgpu/shader/execution/exp2.bin": "9b6fc8e4", + "webgpu/shader/execution/faceForward.bin": "fd625afb", + "webgpu/shader/execution/floor.bin": "1bd71153", + "webgpu/shader/execution/fma.bin": "e8b8fb81", + "webgpu/shader/execution/fract.bin": "1418c869", + "webgpu/shader/execution/frexp.bin": "f3479537", + "webgpu/shader/execution/inverseSqrt.bin": "bffe5bb5", + "webgpu/shader/execution/ldexp.bin": "67a1429a", + "webgpu/shader/execution/length.bin": "96879f26", + "webgpu/shader/execution/log.bin": "6236e8ce", + "webgpu/shader/execution/log2.bin": "80b3b25e", + "webgpu/shader/execution/max.bin": "d1cd18d4", + "webgpu/shader/execution/min.bin": "bc675ea4", + "webgpu/shader/execution/mix.bin": "8a363e70", + "webgpu/shader/execution/modf.bin": "95090ab0", + "webgpu/shader/execution/normalize.bin": "94c1c225", + "webgpu/shader/execution/pack2x16float.bin": "ecbb0ff5", + "webgpu/shader/execution/pow.bin": "ed240d1", + "webgpu/shader/execution/quantizeToF16.bin": "24a86b02", + "webgpu/shader/execution/radians.bin": "382fbea0", + "webgpu/shader/execution/reflect.bin": "937f1d8e", + "webgpu/shader/execution/refract.bin": "16c2bae1", + "webgpu/shader/execution/round.bin": "f2c27411", + "webgpu/shader/execution/saturate.bin": "af2dac30", + "webgpu/shader/execution/sign.bin": "6e934f", + "webgpu/shader/execution/sin.bin": "5fd7855a", + "webgpu/shader/execution/sinh.bin": "f65c0861", + "webgpu/shader/execution/smoothstep.bin": "d0e5332b", + "webgpu/shader/execution/sqrt.bin": "8b6e7172", + "webgpu/shader/execution/step.bin": "a3aaf9b5", + "webgpu/shader/execution/tan.bin": "49d64878", + "webgpu/shader/execution/tanh.bin": "5610833b", + "webgpu/shader/execution/transpose.bin": "28f03a75", + "webgpu/shader/execution/trunc.bin": "7c399303", + "webgpu/shader/execution/unpack2x16float.bin": "1686700c", + "webgpu/shader/execution/unpack2x16snorm.bin": "4e8ccf79", + "webgpu/shader/execution/unpack2x16unorm.bin": "a5629600", + "webgpu/shader/execution/unpack4x8snorm.bin": "337336eb", + "webgpu/shader/execution/unpack4x8unorm.bin": "1f7c1896", + "webgpu/shader/execution/unary/af_arithmetic.bin": "af37f0ac", + "webgpu/shader/execution/unary/af_assignment.bin": "7e4244d4", + "webgpu/shader/execution/unary/bool_conversion.bin": "7b188e5c", + "webgpu/shader/execution/unary/f16_arithmetic.bin": "6d58b26a", + "webgpu/shader/execution/unary/f16_conversion.bin": "b8ea2ca8", + "webgpu/shader/execution/unary/f32_arithmetic.bin": "d17c61e0", + "webgpu/shader/execution/unary/f32_conversion.bin": "9ec984a0", + "webgpu/shader/execution/unary/i32_arithmetic.bin": "8126e1ca", + "webgpu/shader/execution/unary/i32_conversion.bin": "66523c55", + "webgpu/shader/execution/unary/u32_conversion.bin": "7cd7eb5e", + "webgpu/shader/execution/unary/ai_assignment.bin": "be39e750", + "webgpu/shader/execution/binary/ai_arithmetic.bin": "9c79c804", + "webgpu/shader/execution/unary/ai_arithmetic.bin": "ba3fd875", + "webgpu/shader/execution/binary/af_matrix_matrix_multiplication.bin": "cd144e74", + "webgpu/shader/execution/binary/af_matrix_scalar_multiplication.bin": "10e8eb15", + "webgpu/shader/execution/binary/af_matrix_vector_multiplication.bin": "83fa4748" } \ 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 1364cdb4e4f2..b6cd790bd4db 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1940,6 +1940,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,textureSampleCompare:array_index_argument:*": { "subcaseMS": 1.932 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleCompare:coords_argument:*": { "subcaseMS": 1.282 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleCompare:depth_ref_argument:*": { "subcaseMS": 1.563 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleCompare:offset_argument,non_const:*": { "subcaseMS": 1.720 }, + "webgpu:shader,validation,expression,call,builtin,textureSampleCompare:offset_argument:*": { "subcaseMS": 1.540 }, "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 index 0d63c059d719..1588eb05b751 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/textureSample.spec.ts @@ -18,6 +18,7 @@ import { isConvertible, ScalarType, VectorType, + isUnsignedType, } from '../../../../../util/conversion.js'; import { ShaderValidationTest } from '../../../shader_validation_test.js'; @@ -39,7 +40,11 @@ const kValidTextureSampleParameterTypes: { [n: string]: TextureSampleArguments } '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_2d_array: { + coordsArgType: Type.vec2f, + hasArrayIndexArg: true, + offsetArgType: Type.vec2i, + }, texture_depth_cube: { coordsArgType: Type.vec3f }, texture_depth_cube_array: { coordsArgType: Type.vec3f, hasArrayIndexArg: true }, } as const; @@ -61,6 +66,8 @@ Validates that only incorrect coords arguments are rejected by ${builtin} .combine('coordType', keysOf(kValuesTypes)) .beginSubcases() .combine('value', [-1, 0, 1] as const) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.coordType]) && t.value < 0) .expand('offset', ({ textureType }) => { const offset = kValidTextureSampleParameterTypes[textureType].offsetArgType; return offset ? [false, true] : [false]; @@ -101,12 +108,12 @@ Validates that only incorrect array_index arguments are rejected by ${builtin} u .combine('textureType', kTextureTypes) // filter out types with no array_index - .filter( - ({ textureType }) => !!kValidTextureSampleParameterTypes[textureType].hasArrayIndexArg - ) + .filter(t => !!kValidTextureSampleParameterTypes[t.textureType].hasArrayIndexArg) .combine('arrayIndexType', keysOf(kValuesTypes)) .beginSubcases() .combine('value', [-9, -8, 0, 7, 8]) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.arrayIndexType]) && t.value < 0) ) .fn(t => { const { textureType, arrayIndexType, value } = t.params; @@ -141,13 +148,12 @@ Validates that only incorrect offset arguments are rejected by ${builtin} u .combine('textureType', kTextureTypes) // filter out types with no offset - .filter( - ({ textureType }) => - kValidTextureSampleParameterTypes[textureType].offsetArgType !== undefined - ) + .filter(t => !!kValidTextureSampleParameterTypes[t.textureType].offsetArgType) .combine('offsetType', keysOf(kValuesTypes)) .beginSubcases() .combine('value', [-9, -8, 0, 7, 8]) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.offsetType]) && t.value < 0) ) .fn(t => { const { textureType, offsetType, value } = t.params; @@ -187,10 +193,7 @@ Validates that only non-const offset arguments are rejected by ${builtin} .combine('textureType', kTextureTypes) .combine('varType', ['c', 'u', 'l']) // filter out types with no offset - .filter( - ({ textureType }) => - kValidTextureSampleParameterTypes[textureType].offsetArgType !== undefined - ) + .filter(t => !!kValidTextureSampleParameterTypes[t.textureType].offsetArgType) ) .fn(t => { const { textureType, varType } = t.params; @@ -200,15 +203,14 @@ Validates that only non-const offset arguments are rejected by ${builtin} 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 { +@fragment fn fs() -> @location(0) vec4f { const c = 1; - let l = ${offsetArgType}(${castWGSL}(p.x)); + let l = ${offsetArgType!.create(0).wgsl()}; let v = textureSample(t, s, ${coordWGSL}${arrayWGSL}, ${offsetWGSL}); return vec4f(0); } diff --git a/src/webgpu/shader/validation/expression/call/builtin/textureSampleCompare.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/textureSampleCompare.spec.ts new file mode 100644 index 000000000000..21269b211c20 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/textureSampleCompare.spec.ts @@ -0,0 +1,249 @@ +const builtin = 'textureSampleCompare'; +export const description = ` +Validation tests for the ${builtin}() builtin. + +* test textureSampleCompare coords parameter must be correct type +* test textureSampleCompare array_index parameter must be correct type +* test textureSampleCompare depth_ref parameter must be correct type +* test textureSampleCompare offset parameter must be correct type +* test textureSampleCompare offset parameter must be a const-expression +* test textureSampleCompare 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, + isUnsignedType, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +type TextureSampleCompareArguments = { + coordsArgType: ScalarType | VectorType; + hasArrayIndexArg?: boolean; + offsetArgType?: VectorType; +}; + +const kValidTextureSampleCompareParameterTypes: { [n: string]: TextureSampleCompareArguments } = { + texture_depth_2d: { coordsArgType: Type.vec2f, offsetArgType: Type.vec2i }, + texture_depth_2d_array: { + coordsArgType: Type.vec2f, + hasArrayIndexArg: true, + offsetArgType: Type.vec2i, + }, + texture_depth_cube: { coordsArgType: Type.vec3f }, + texture_depth_cube_array: { coordsArgType: Type.vec3f, hasArrayIndexArg: true }, +} as const; + +const kTextureTypes = keysOf(kValidTextureSampleCompareParameterTypes); +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(kValidTextureSampleCompareParameterTypes)) + .combine('coordType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-1, 0, 1] as const) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.coordType]) && t.value < 0) + .expand('offset', ({ textureType }) => { + const offset = kValidTextureSampleCompareParameterTypes[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, + } = kValidTextureSampleCompareParameterTypes[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_comparison; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSampleCompare(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(t => !!kValidTextureSampleCompareParameterTypes[t.textureType].hasArrayIndexArg) + .combine('arrayIndexType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-9, -8, 0, 7, 8]) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.arrayIndexType]) && t.value < 0) + ) + .fn(t => { + const { textureType, arrayIndexType, value } = t.params; + const arrayIndexArgType = kValuesTypes[arrayIndexType]; + const args = [arrayIndexArgType.create(value)]; + const { coordsArgType, offsetArgType } = kValidTextureSampleCompareParameterTypes[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_comparison; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSampleCompare(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('depth_ref_argument') + .desc( + ` +Validates that only incorrect depth_ref arguments are rejected by ${builtin} +` + ) + .params(u => + u + .combine('textureType', kTextureTypes) + .combine('depthRefType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-1, 0, 1]) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.depthRefType]) && t.value < 0) + ) + .fn(t => { + const { textureType, depthRefType, value } = t.params; + const depthRefArgType = kValuesTypes[depthRefType]; + const args = [depthRefArgType.create(value)]; + const { coordsArgType, hasArrayIndexArg, offsetArgType } = + kValidTextureSampleCompareParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const depthRefWGSL = args.map(arg => arg.wgsl()).join(', '); + const offsetWGSL = offsetArgType ? `, ${offsetArgType.create(0).wgsl()}` : ''; + + const code = ` +@group(0) @binding(0) var s: sampler_comparison; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSampleCompare(t, s, ${coordWGSL}${arrayWGSL}, ${depthRefWGSL}${offsetWGSL}); + return vec4f(0); +} +`; + const expectSuccess = isConvertible(depthRefArgType, 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(t => !!kValidTextureSampleCompareParameterTypes[t.textureType].offsetArgType) + .combine('offsetType', keysOf(kValuesTypes)) + .beginSubcases() + .combine('value', [-9, -8, 0, 7, 8]) + // filter out unsigned types with negative values + .filter(t => isUnsignedType(kValuesTypes[t.offsetType]) && t.value < 0) + ) + .fn(t => { + const { textureType, offsetType, value } = t.params; + const offsetArgType = kValuesTypes[offsetType]; + const args = [offsetArgType.create(value)]; + const { + coordsArgType, + hasArrayIndexArg, + offsetArgType: offsetRequiredType, + } = kValidTextureSampleCompareParameterTypes[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_comparison; +@group(0) @binding(1) var t: ${textureType}; +@fragment fn fs() -> @location(0) vec4f { + let v = textureSampleCompare(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(t => !!kValidTextureSampleCompareParameterTypes[t.textureType].offsetArgType) + ) + .fn(t => { + const { textureType, varType } = t.params; + const { coordsArgType, hasArrayIndexArg, offsetArgType } = + kValidTextureSampleCompareParameterTypes[textureType]; + + const coordWGSL = coordsArgType.create(0).wgsl(); + const arrayWGSL = hasArrayIndexArg ? ', 0' : ''; + const offsetWGSL = `${offsetArgType}(${varType})`; + + const code = ` +@group(0) @binding(0) var s: sampler_comparison; +@group(0) @binding(1) var t: ${textureType}; +@group(0) @binding(2) var u: ${offsetArgType}; +@fragment fn fs() -> @location(0) vec4f { + const c = 1; + let l = ${offsetArgType?.create(0).wgsl()}; + let v = textureSampleCompare(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..58adcd49e9a8 100644 --- a/src/webgpu/util/conversion.ts +++ b/src/webgpu/util/conversion.ts @@ -2234,6 +2234,17 @@ export function isFloatType(ty: Type): boolean { return false; } +/** + * @returns if `ty` is an unsigned type. + */ +export function isUnsignedType(ty: Type): boolean { + if (ty instanceof ScalarType) { + return ty.kind === 'u8' || ty.kind === 'u16' || ty.kind === 'u32'; + } else { + return isUnsignedType(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) {