Skip to content

Commit

Permalink
Validation tests for resource compatibility of render pipelines (#3441)
Browse files Browse the repository at this point in the history
* Reuses compute pipeline resource infrastructure
  * small update to generate consistent fragment shader
* Filters out writable storge buffer and storage texture resources from
  the api side for vertex shaders
  • Loading branch information
alan-baker authored Feb 28, 2024
1 parent 69b12ab commit c0181cf
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -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
);
});
11 changes: 9 additions & 2 deletions src/webgpu/api/validation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,15 @@ export function getWGSLShaderForResource(stage: string, resource: Resource): str
code += `@workgroup_size(1)`;
}

const retTy = stage === 'vertex' ? ' -> @builtin(position) vec4f' : '';
const retVal = stage === 'vertex' ? 'return vecf();' : '';
let retTy = '';
let retVal = '';
if (stage === 'vertex') {
retTy = ' -> @builtin(position) vec4f';
retVal = 'return vec4f();';
} else if (stage === 'fragment') {
retTy = ' -> @location(0) vec4f';
retVal = 'return vec4f();';
}
code += `
fn main() ${retTy} {
_ = ${resource.staticUse ?? 'res'};
Expand Down
1 change: 1 addition & 0 deletions src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@
"webgpu:api,validation,render_pipeline,overrides:value,validation_error,vertex:*": { "subcaseMS": 6.022 },
"webgpu:api,validation,render_pipeline,primitive_state:strip_index_format:*": { "subcaseMS": 5.267 },
"webgpu:api,validation,render_pipeline,primitive_state:unclipped_depth:*": { "subcaseMS": 1.025 },
"webgpu:api,validation,render_pipeline,resource_compatibility:resource_compatibility:*": { "subcaseMS": 1.025 },
"webgpu:api,validation,render_pipeline,shader_module:device_mismatch:*": { "subcaseMS": 0.700 },
"webgpu:api,validation,render_pipeline,shader_module:invalid,fragment:*": { "subcaseMS": 5.800 },
"webgpu:api,validation,render_pipeline,shader_module:invalid,vertex:*": { "subcaseMS": 15.151 },
Expand Down

0 comments on commit c0181cf

Please sign in to comment.