From cdd0502a5724ac190cd5a43fe2fe7952893336af Mon Sep 17 00:00:00 2001 From: Greggman Date: Thu, 8 Aug 2024 12:40:50 -0700 Subject: [PATCH] WGSL execution tests for textureSampleBaseClampToEdge (#3896) --- src/webgpu/listing_meta.json | 1 + .../textureSampleBaseClampToEdge.spec.ts | 115 ++++++++++++++++++ .../expression/call/builtin/texture_utils.ts | 18 ++- 3 files changed, 128 insertions(+), 6 deletions(-) create mode 100644 src/webgpu/shader/execution/expression/call/builtin/textureSampleBaseClampToEdge.spec.ts diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 436fcd6ce891..85fe0bdc6a8b 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1584,6 +1584,7 @@ "webgpu:shader,execution,expression,call,builtin,textureSample:sampled_3d_coords:*": { "subcaseMS": 36.002 }, "webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_2d_coords:*": { "subcaseMS": 92.500 }, "webgpu:shader,execution,expression,call,builtin,textureSample:sampled_array_3d_coords:*": { "subcaseMS": 20.200 }, + "webgpu:shader,execution,expression,call,builtin,textureSampleBaseClampToEdge:2d_coords:*": { "subcaseMS": 55.401 }, "webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_2d_coords:*": { "subcaseMS": 585.100 }, "webgpu:shader,execution,expression,call,builtin,textureSampleBias:arrayed_3d_coords:*": { "subcaseMS": 121.600 }, "webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:*": { "subcaseMS": 48.601 }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/textureSampleBaseClampToEdge.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/textureSampleBaseClampToEdge.spec.ts new file mode 100644 index 000000000000..452c3b4df710 --- /dev/null +++ b/src/webgpu/shader/execution/expression/call/builtin/textureSampleBaseClampToEdge.spec.ts @@ -0,0 +1,115 @@ +export const description = ` +Execution tests for textureSampleBaseClampToEdge +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../../../gpu_test.js'; +import { TexelView } from '../../../../../util/texture/texel_view.js'; + +import { + checkCallResults, + createTextureWithRandomDataAndGetTexels, + createVideoFrameWithRandomDataAndGetTexels, + doTextureCalls, + generateTextureBuiltinInputs2D, + kSamplePointMethods, + TextureCall, + vec2, + WGSLTextureSampleTest, +} from './texture_utils.js'; + +export const g = makeTestGroup(WGSLTextureSampleTest); + +async function createTextureAndDataForTest( + t: GPUTest, + descriptor: GPUTextureDescriptor, + isExternal: boolean +): Promise<{ + texels: TexelView[]; + texture: GPUTexture | GPUExternalTexture; + videoFrame?: VideoFrame; +}> { + if (isExternal) { + const { texels, videoFrame } = createVideoFrameWithRandomDataAndGetTexels(descriptor.size); + const texture = t.device.importExternalTexture({ source: videoFrame }); + return { texels, texture, videoFrame }; + } else { + return await createTextureWithRandomDataAndGetTexels(t, descriptor); + } +} + +g.test('2d_coords') + .specURL('https://www.w3.org/TR/WGSL/#texturesamplebaseclamptoedge') + .desc( + ` +fn textureSampleBaseClampToEdge(t: texture_2d, s: sampler, coords: vec2) -> vec4 +fn textureSampleBaseClampToEdge(t: texture_external, s: sampler, coords: vec2) -> vec4 + + +Parameters: + * t The texture to sample. + * s The sampler type. + * coords The texture coordinates used for sampling. +` + ) + .params(u => + u + .combine('textureType', ['texture_2d', 'texture_external'] as const) + .beginSubcases() + .combine('samplePoints', kSamplePointMethods) + .combine('addressModeU', ['clamp-to-edge', 'repeat', 'mirror-repeat'] as const) + .combine('addressModeV', ['clamp-to-edge', 'repeat', 'mirror-repeat'] as const) + .combine('minFilter', ['nearest', 'linear'] as const) + ) + .fn(async t => { + const { textureType, samplePoints, addressModeU, addressModeV, minFilter } = t.params; + + const descriptor: GPUTextureDescriptor = { + format: 'rgba8unorm', + size: [8, 8], + usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING, + mipLevelCount: 3, + }; + + const isExternal = textureType === 'texture_external'; + const { texture, texels, videoFrame } = await createTextureAndDataForTest( + t, + descriptor, + isExternal + ); + try { + const sampler: GPUSamplerDescriptor = { + addressModeU, + addressModeV, + minFilter, + magFilter: minFilter, + mipmapFilter: minFilter, + }; + + const calls: TextureCall[] = generateTextureBuiltinInputs2D(50, { + method: samplePoints, + sampler, + descriptor, + hashInputs: [samplePoints, addressModeU, addressModeV, minFilter], + }).map(({ coords }) => { + return { + builtin: 'textureSampleBaseClampToEdge', + coordType: 'f', + coords, + }; + }); + const viewDescriptor = {}; + const results = await doTextureCalls(t, texture, viewDescriptor, textureType, sampler, calls); + const res = await checkCallResults( + t, + { texels, descriptor, viewDescriptor }, + textureType, + sampler, + calls, + results + ); + t.expectOK(res); + } finally { + videoFrame?.close(); + } + }); diff --git a/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts b/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts index d24dabb5cdda..e997833a137f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts @@ -477,7 +477,7 @@ export interface TextureCallArgs { } export interface TextureCall extends TextureCallArgs { - builtin: 'textureSample' | 'textureLoad' | 'textureSampleLevel'; + builtin: 'textureLoad' | 'textureSample' | 'textureSampleBaseClampToEdge' | 'textureSampleLevel'; coordType: 'f' | 'i' | 'u'; levelType?: 'i' | 'u' | 'f'; arrayIndexType?: 'i' | 'u'; @@ -652,11 +652,14 @@ export function softwareTextureReadMipLevel( texture.descriptor.size, mipLevel ); - const addressMode = [ - sampler?.addressModeU ?? 'clamp-to-edge', - sampler?.addressModeV ?? 'clamp-to-edge', - sampler?.addressModeW ?? 'clamp-to-edge', - ]; + const addressMode: GPUAddressMode[] = + call.builtin === 'textureSampleBaseClampToEdge' + ? ['clamp-to-edge', 'clamp-to-edge', 'clamp-to-edge'] + : [ + sampler?.addressModeU ?? 'clamp-to-edge', + sampler?.addressModeV ?? 'clamp-to-edge', + sampler?.addressModeW ?? 'clamp-to-edge', + ]; const isCube = texture.viewDescriptor.dimension === 'cube' || @@ -682,6 +685,7 @@ export function softwareTextureReadMipLevel( switch (call.builtin) { case 'textureSample': + case 'textureSampleBaseClampToEdge': case 'textureSampleLevel': { let coords = toArray(call.coords!); @@ -830,6 +834,8 @@ export function softwareTextureReadMipLevel( : load(call.coords!); return convertPerTexelComponentToResultFormat(out, format); } + default: + unreachable(); } }