diff options
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts')
-rw-r--r-- | dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts new file mode 100644 index 0000000000..5d6bc8d125 --- /dev/null +++ b/dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts @@ -0,0 +1,95 @@ +export const description = ` +Tests for resource compatibilty between pipeline layout and shader modules + `; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { keysOf } from '../../../../common/util/data_tables.js'; +import { + kAPIResources, + getWGSLShaderForResource, + getAPIBindGroupLayoutForResource, + doResourcesMatch, +} from '../utils.js'; + +import { CreateRenderPipelineValidationTest } from './common.js'; + +export const g = makeTestGroup(CreateRenderPipelineValidationTest); + +g.test('resource_compatibility') + .desc( + 'Tests validation of resource (bind group) compatibility between pipeline layout and WGSL shader' + ) + .params(u => + u // + .combine('stage', ['vertex', 'fragment'] as const) + .combine('apiResource', keysOf(kAPIResources)) + .filter(t => { + const res = kAPIResources[t.apiResource]; + if (t.stage === 'vertex') { + if (res.buffer && res.buffer.type === 'storage') { + return false; + } + if (res.storageTexture && res.storageTexture.access !== 'read-only') { + return false; + } + } + return true; + }) + .beginSubcases() + .combine('isAsync', [true, false] as const) + .combine('wgslResource', keysOf(kAPIResources)) + ) + .fn(t => { + const apiResource = kAPIResources[t.params.apiResource]; + const wgslResource = kAPIResources[t.params.wgslResource]; + t.skipIf( + wgslResource.storageTexture !== undefined && + wgslResource.storageTexture.access !== 'write-only' && + !t.hasLanguageFeature('readonly_and_readwrite_storage_textures'), + 'Storage textures require language feature' + ); + const emptyVS = ` +@vertex +fn main() -> @builtin(position) vec4f { + return vec4f(); +} +`; + const emptyFS = ` +@fragment +fn main() -> @location(0) vec4f { + return vec4f(); +} +`; + + const code = getWGSLShaderForResource(t.params.stage, wgslResource); + const vsCode = t.params.stage === 'vertex' ? code : emptyVS; + const fsCode = t.params.stage === 'fragment' ? code : emptyFS; + const gpuStage: GPUShaderStageFlags = + t.params.stage === 'vertex' ? GPUShaderStage.VERTEX : GPUShaderStage.FRAGMENT; + const layout = t.device.createPipelineLayout({ + bindGroupLayouts: [getAPIBindGroupLayoutForResource(t.device, gpuStage, apiResource)], + }); + + const descriptor = { + layout, + vertex: { + module: t.device.createShaderModule({ + code: vsCode, + }), + entryPoint: 'main', + }, + fragment: { + module: t.device.createShaderModule({ + code: fsCode, + }), + entryPoint: 'main', + targets: [{ format: 'rgba8unorm' }] as const, + }, + }; + + t.doCreateRenderPipelineTest( + t.params.isAsync, + doResourcesMatch(apiResource, wgslResource), + descriptor + ); + }); |