From 7eedd5adf748c46d81623960c79cec8f575cc9a0 Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Wed, 18 Dec 2024 15:41:45 +0800 Subject: [PATCH] Add validation test about creating pipeline layout with null bind group layout (#4076) * Add validation tests on the creation of pipeline layout with null bind group layout * Update webgpu/types * Test 'undefined' in `bindGroupLayouts` * Address reviewer's comments --- package-lock.json | 29 ++---- package.json | 2 +- .../validation/createPipelineLayout.spec.ts | 94 +++++++++++++++++++ 3 files changed, 103 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd59eb95b21c..439c54ed83d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@types/w3c-image-capture": "^1.0.10", "@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/parser": "^6.9.1", - "@webgpu/types": "^0.1.51", + "@webgpu/types": "^0.1.52", "ansi-colors": "4.1.3", "babel-plugin-add-header-comment": "^1.0.3", "babel-plugin-const-enum": "^1.2.0", @@ -1539,17 +1539,10 @@ "dev": true }, "node_modules/@webgpu/types": { -<<<<<<< HEAD - "version": "0.1.51", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.51.tgz", - "integrity": "sha512-ktR3u64NPjwIViNCck+z9QeyN0iPkQCUOQ07ZCV1RzlkfP+olLTeEZ95O1QHS+v4w9vJeY9xj/uJuSphsHy5rQ==", -======= - "version": "0.1.50", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.50.tgz", - "integrity": "sha512-GjG3CQV7SyWk/lEXqFPuKchRPHIBbD317Gj8NUqqB+UOnQlOYtjGLCTRIWzO9Ta698LVzlBCSE9XKqBSWpIDmg==", ->>>>>>> 8a80203467ffcb3f87bb6a7f74655a6e1043d051 - "dev": true, - "license": "BSD-3-Clause" + "version": "0.1.52", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.52.tgz", + "integrity": "sha512-eI883Nlag2hGIkhXxAnq8s4APpqXWuPL3Gbn2ghiU12UjLvfCbVqHK4XfXl3eLRTatqcMmeK7jws7IwWsGfbzw==", + "dev": true }, "node_modules/abbrev": { "version": "1.1.1", @@ -10083,15 +10076,9 @@ "dev": true }, "@webgpu/types": { -<<<<<<< HEAD - "version": "0.1.51", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.51.tgz", - "integrity": "sha512-ktR3u64NPjwIViNCck+z9QeyN0iPkQCUOQ07ZCV1RzlkfP+olLTeEZ95O1QHS+v4w9vJeY9xj/uJuSphsHy5rQ==", -======= - "version": "0.1.50", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.50.tgz", - "integrity": "sha512-GjG3CQV7SyWk/lEXqFPuKchRPHIBbD317Gj8NUqqB+UOnQlOYtjGLCTRIWzO9Ta698LVzlBCSE9XKqBSWpIDmg==", ->>>>>>> 8a80203467ffcb3f87bb6a7f74655a6e1043d051 + "version": "0.1.52", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.52.tgz", + "integrity": "sha512-eI883Nlag2hGIkhXxAnq8s4APpqXWuPL3Gbn2ghiU12UjLvfCbVqHK4XfXl3eLRTatqcMmeK7jws7IwWsGfbzw==", "dev": true }, "abbrev": { diff --git a/package.json b/package.json index cef3de27ed1d..959f479791f6 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@types/w3c-image-capture": "^1.0.10", "@typescript-eslint/eslint-plugin": "^6.9.1", "@typescript-eslint/parser": "^6.9.1", - "@webgpu/types": "^0.1.51", + "@webgpu/types": "^0.1.52", "ansi-colors": "4.1.3", "babel-plugin-add-header-comment": "^1.0.3", "babel-plugin-const-enum": "^1.2.0", diff --git a/src/webgpu/api/validation/createPipelineLayout.spec.ts b/src/webgpu/api/validation/createPipelineLayout.spec.ts index 00e64cac749b..07434d4e89e5 100644 --- a/src/webgpu/api/validation/createPipelineLayout.spec.ts +++ b/src/webgpu/api/validation/createPipelineLayout.spec.ts @@ -6,6 +6,7 @@ TODO: review existing tests, write descriptions, and make sure tests are complet import { makeTestGroup } from '../../../common/framework/test_group.js'; import { bufferBindingTypeInfo, kBufferBindingTypes } from '../../capability_info.js'; +import { GPUConst } from '../../constants.js'; import { ValidationTest } from './validation_test.js'; @@ -162,3 +163,96 @@ g.test('bind_group_layouts,device_mismatch') t.device.createPipelineLayout({ bindGroupLayouts: [layout0, layout1] }); }, mismatched); }); + +const MaybeNullBindGroupLayoutTypes = ['Null', 'Undefined', 'Empty', 'NonEmpty'] as const; + +g.test('bind_group_layouts,null_bind_group_layouts') + .desc( + ` + Tests that it is valid to create a pipeline layout with null bind group layouts. + ` + ) + .paramsSubcasesOnly(u => + u // + .combine('bindGroupLayoutCount', [1, 2, 3, 4] as const) + .combine('bindGroupLayout0', MaybeNullBindGroupLayoutTypes) + .expand('bindGroupLayout1', p => + p.bindGroupLayoutCount > 1 ? MaybeNullBindGroupLayoutTypes : (['Null'] as const) + ) + .expand('bindGroupLayout2', p => + p.bindGroupLayoutCount > 2 ? MaybeNullBindGroupLayoutTypes : (['Null'] as const) + ) + .expand('bindGroupLayout3', p => + p.bindGroupLayoutCount > 3 ? MaybeNullBindGroupLayoutTypes : (['Null'] as const) + ) + .filter(p => { + // Only test cases where at least one of the bind group layouts is null. + const allBGLs = [ + p.bindGroupLayout0, + p.bindGroupLayout1, + p.bindGroupLayout2, + p.bindGroupLayout3, + ]; + const bgls = allBGLs.slice(0, p.bindGroupLayoutCount); + return bgls.includes('Null') || bgls.includes('Undefined'); + }) + ) + .fn(t => { + const { + bindGroupLayoutCount, + bindGroupLayout0, + bindGroupLayout1, + bindGroupLayout2, + bindGroupLayout3, + } = t.params; + + const emptyBindGroupLayout = t.device.createBindGroupLayout({ + entries: [], + }); + const nonEmptyBindGroupLayout = t.device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: GPUConst.ShaderStage.COMPUTE, + texture: {}, + }, + ], + }); + + const bindGroupLayouts: (GPUBindGroupLayout | null | undefined)[] = []; + + const AddBindGroupLayout = function ( + bindGroupLayoutType: (typeof MaybeNullBindGroupLayoutTypes)[number] + ) { + switch (bindGroupLayoutType) { + case 'Null': + bindGroupLayouts.push(null); + break; + case 'Undefined': + bindGroupLayouts.push(undefined); + break; + case 'Empty': + bindGroupLayouts.push(emptyBindGroupLayout); + break; + case 'NonEmpty': + bindGroupLayouts.push(nonEmptyBindGroupLayout); + break; + } + }; + + AddBindGroupLayout(bindGroupLayout0); + if (bindGroupLayoutCount > 1) { + AddBindGroupLayout(bindGroupLayout1); + } + if (bindGroupLayoutCount > 2) { + AddBindGroupLayout(bindGroupLayout2); + } + if (bindGroupLayoutCount > 3) { + AddBindGroupLayout(bindGroupLayout3); + } + + const kShouldError = false; + t.expectValidationError(() => { + t.device.createPipelineLayout({ bindGroupLayouts }); + }, kShouldError); + });