summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/api/validation/render_pipeline/resource_compatibility.spec.ts
diff options
context:
space:
mode:
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.ts95
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
+ );
+ });