diff --git a/src/webgpu/api/operation/render_pipeline/vertex_only_render_pipeline.spec.ts b/src/webgpu/api/operation/render_pipeline/vertex_only_render_pipeline.spec.ts new file mode 100644 index 000000000000..ef2d108f1e1d --- /dev/null +++ b/src/webgpu/api/operation/render_pipeline/vertex_only_render_pipeline.spec.ts @@ -0,0 +1,29 @@ +export const description = ` +Test vertex-only render pipeline. +`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { GPUTest } from '../../../gpu_test.js'; + +class F extends GPUTest {} + +export const g = makeTestGroup(F); + +g.test('draw_depth_and_stencil_with_vertex_only_pipeline') + .desc( + ` +TODO: +- Test drawing depth and stencil with vertex-only render pipelines by + 1. Create a color attachment and depth-stencil attachment of 4 pixels in a line, clear the color + to RGBA(0.0, 0.0, 0.0, 0.0), depth to 0.0 and stencil to 0x0 + 2. Use a depth and stencil test disabled vertex-only render pipeline to modify the depth of middle + 2 pixels to 0.5, while leaving stencil unchanged + 3. Use another depth and stencil test disabled vertex-only render pipeline to modify the stencil + of right 2 pixels to 0x1, while leaving depth unchanged + 4. Use a complete render pipeline to draw all 4 pixels with color RGBA(0.0, 1.0, 0.0, 1.0), but + with depth test requiring depth no less than 0.5 and stencil test requiring stencil equals to 0x1 + 5. Validate that only the third pixel is of color RGBA(0.0, 1.0, 0.0, 1.0), and all other pixels + are RGBA(0.0, 0.0, 0.0, 0.0). +` + ) + .unimplemented(); diff --git a/src/webgpu/api/validation/createRenderPipeline.spec.ts b/src/webgpu/api/validation/createRenderPipeline.spec.ts index 9bda8d3436b5..06097ebab13c 100644 --- a/src/webgpu/api/validation/createRenderPipeline.spec.ts +++ b/src/webgpu/api/validation/createRenderPipeline.spec.ts @@ -91,6 +91,7 @@ class F extends ValidationTest { sampleCount?: number; depthStencil?: GPUDepthStencilState; fragmentShaderCode?: string; + noFragment?: boolean; } = {} ): GPURenderPipelineDescriptor { const defaultTargets: GPUColorTargetState[] = [{ format: 'rgba8unorm' }]; @@ -103,6 +104,7 @@ class F extends ValidationTest { kTextureFormatInfo[targets[0] ? targets[0].format : 'rgba8unorm'].sampleType, 4 ), + noFragment = false, } = options; return { @@ -115,13 +117,15 @@ class F extends ValidationTest { }), entryPoint: 'main', }, - fragment: { - module: this.device.createShaderModule({ - code: fragmentShaderCode, - }), - entryPoint: 'main', - targets, - }, + fragment: noFragment + ? undefined + : { + module: this.device.createShaderModule({ + code: fragmentShaderCode, + }), + entryPoint: 'main', + targets, + }, layout: this.getPipelineLayout(), primitive: { topology }, multisample: { count: sampleCount }, @@ -174,7 +178,45 @@ g.test('basic_use_of_createRenderPipeline') t.doCreateRenderPipelineTest(isAsync, true, descriptor); }); -g.test('at_least_one_color_state_is_required') +g.test('create_vertex_only_pipeline_with_without_depth_stencil_state') + .desc( + `Test creating vertex-only render pipeline. A vertex-only render pipeline have no fragment +state (and thus have no color state), and can be create with or without depth stencil state.` + ) + .params(u => + u + .combine('isAsync', [false, true]) + .beginSubcases() + .combine('depthStencilFormat', [ + 'depth24plus', + 'depth24plus-stencil8', + 'depth32float', + '', + ] as const) + .combine('haveColor', [false, true]) + ) + .fn(async t => { + const { isAsync, depthStencilFormat, haveColor } = t.params; + + let depthStencilState: GPUDepthStencilState | undefined; + if (depthStencilFormat === '') { + depthStencilState = undefined; + } else { + depthStencilState = { format: depthStencilFormat }; + } + + // Having targets or not should have no effect in result, since it will not appear in the + // descriptor in vertex-only render pipeline + const descriptor = t.getDescriptor({ + noFragment: true, + depthStencil: depthStencilState, + targets: haveColor ? [{ format: 'rgba8unorm' }] : [], + }); + + t.doCreateRenderPipelineTest(isAsync, true, descriptor); + }); + +g.test('at_least_one_color_state_is_required_for_complete_pipeline') .params(u => u.combine('isAsync', [false, true])) .fn(async t => { const { isAsync } = t.params;