| <!DOCTYPE html> |
| <meta charset=utf-8> |
| <title>Test Error Scopes.</title> |
| <body> |
| <script src="js/webgpu-functions.js"></script> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script> |
| const positionLocation = 0; |
| const colorLocation = 1; |
| |
| const colorOffset = 4 * 4; |
| const vertexStride = 8 * 4; |
| |
| const whlslSource = ` |
| struct FragmentData { |
| float4 position : SV_Position; |
| float4 color : attribute(${colorLocation}); |
| } |
| |
| vertex FragmentData vertexMain(float4 position : attribute(${positionLocation}), float4 color : attribute(${colorLocation})) |
| { |
| FragmentData out; |
| |
| out.position = position; |
| out.color = color; |
| |
| return out; |
| } |
| |
| fragment float4 fragmentMain(float4 color : attribute(${colorLocation})) : SV_Target 0 |
| { |
| return color; |
| } |
| `; |
| |
| let goodRenderPipelineDescriptor, goodModule; |
| |
| let tests = {}; |
| |
| tests["GPURenderPipeline creation succeeds with no errors."] = async device => { |
| goodModule = device.createShaderModule({ code: whlslSource }); |
| |
| goodRenderPipelineDescriptor = { |
| vertexStage: { module: goodModule, entryPoint: "vertexMain" }, |
| fragmentStage: { module: goodModule, entryPoint: "fragmentMain" }, |
| primitiveTopology: "triangle-list", |
| colorStates: [{ |
| format: "bgra8unorm", |
| alphaBlend: {}, |
| colorBlend: {} |
| }], |
| vertexInput: { |
| vertexBuffers: [{ |
| stride: vertexStride, |
| attributeSet: [{ |
| shaderLocation: positionLocation, |
| format: "float4" |
| }, { |
| shaderLocation: colorLocation, |
| offset: colorOffset, |
| format: "float4" |
| }] |
| }] |
| } |
| }; |
| Object.freeze(goodRenderPipelineDescriptor); |
| |
| device.pushErrorScope("validation"); |
| device.createRenderPipeline(goodRenderPipelineDescriptor); |
| return popNullError(device); |
| }; |
| |
| tests["Invalid GPUShaderModule for vertex stage should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badShaderModule = device.createShaderModule({ code: "Foo" }); |
| badDescriptor.vertexStage = { module: badShaderModule, entryPoint: "vertexMain" }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Invalid GPUShaderModule for fragment stage should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badShaderModule = device.createShaderModule({ code: "Foo" }); |
| badDescriptor.fragmentStage = { module: badShaderModule, entryPoint: "vertexMain" }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Empty entry point for vertex stage should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badShaderModule = device.createShaderModule({ code: "Foo" }); |
| badDescriptor.vertexStage = { module: badShaderModule, entryPoint: "" }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Invalid GPUTextureFormat in GPUColorStateDescriptor should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| badDescriptor.colorStates = [{ |
| format: "depth32float-stencil8", |
| alphaBlend: {}, |
| colorBlend: {} |
| }]; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Too many GPUColorStateDescriptors should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badColorStates = new Array(100); |
| badColorStates.fill({ |
| format: "bgra8unorm", |
| alphaBlend: {}, |
| colorBlend: {} |
| }); |
| badDescriptor.colorStates = badColorStates; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Too many GPUVertexBufferDescriptors should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badVertexBuffers = new Array(100); |
| badVertexBuffers.fill({ |
| stride: vertexStride, |
| attributeSet: [{ |
| shaderLocation: positionLocation, |
| format: "float4" |
| }] |
| }); |
| badDescriptor.vertexInput = { vertexBuffers: badVertexBuffers }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Too many GPUVertexAttributeDescriptors should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| let badAttributes = new Array(100); |
| badAttributes.fill({ |
| shaderLocation: positionLocation, |
| format: "float4" |
| }); |
| |
| badDescriptor.vertexInput = { |
| vertexBuffers: [{ |
| stride: vertexStride, |
| attributeSet: badAttributes |
| }] |
| }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Duplicate shaderLocation for vertex attributes should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| badDescriptor.vertexInput = { |
| vertexBuffers: [{ |
| stride: vertexStride, |
| attributeSet: [{ |
| shaderLocation: colorLocation, |
| format: "float4" |
| }, { |
| shaderLocation: colorLocation, |
| offset: colorOffset, |
| format: "float4" |
| }] |
| }] |
| }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| tests["Invalid entry point string should fail."] = async device => { |
| let badDescriptor = Object.assign({}, goodRenderPipelineDescriptor); |
| badDescriptor.fragmentStage = { module: goodModule, entryPoint: "bar" }; |
| |
| return createPipelineAndError(device, badDescriptor); |
| }; |
| |
| runTestsWithDevice(tests); |
| |
| const createPipelineAndError = (device, descriptor) => { |
| device.pushErrorScope("validation"); |
| device.createRenderPipeline(descriptor); |
| return popValidationError(device); |
| }; |
| |
| </script> |
| </body> |