| <!DOCTYPE html> |
| <meta charset="utf-8"> |
| <title>WebGPU Hello Triangles</title> |
| <meta name="assert" content="WebGPU correctly renders a green canvas."> |
| <link rel="match" href="blend-triangle-strip-expected.html"> |
| <p>Pass if square canvas below is completely green.</p> |
| <canvas width="400" height="400"></canvas> |
| <script src="js/webgpu-functions.js"></script> |
| <script> |
| if (window.testRunner) |
| testRunner.waitUntilDone(); |
| |
| const positionAttributeNum = 0; |
| |
| const shaderCode = ` |
| #include <metal_stdlib> |
| |
| using namespace metal; |
| |
| struct VertexIn |
| { |
| float4 position [[attribute(${positionAttributeNum})]]; |
| }; |
| |
| struct VertexOut |
| { |
| float4 position [[position]]; |
| float4 color; |
| }; |
| |
| vertex VertexOut vertex_main(VertexIn vertexIn [[stage_in]]) |
| { |
| VertexOut vOut; |
| vOut.position = vertexIn.position; |
| vOut.color = float4(0, 0.5, 0, 0.5); |
| return vOut; |
| } |
| |
| fragment float4 fragment_main(VertexOut v [[stage_in]]) |
| { |
| return v.color; |
| } |
| `; |
| |
| const canvas = document.querySelector("canvas"); |
| |
| async function start(device) { |
| const shaderModule = device.createShaderModule({ code: shaderCode }); |
| |
| const colorStates = [{ |
| format: "bgra8unorm", |
| alphaBlend: { dstFactor: "one" }, |
| colorBlend: { dstFactor: "one" } |
| }]; |
| |
| const vertexInputDescriptor = { |
| indexFormat: "uint32", |
| vertexBuffers: [{ |
| stride: 4 * 4, |
| attributeSet: [{ |
| format: "float4", |
| shaderLocation: positionAttributeNum |
| }] |
| }] |
| }; |
| |
| const pipeline = createBasicPipeline(shaderModule, device, colorStates, null, vertexInputDescriptor); |
| |
| const vertexData = new Float32Array([ |
| -1, 1, 0, 1, |
| -1, -1, 0, 1, |
| 1, 1, 0, 1, |
| 1, -1, 0, 1 |
| ]); |
| const vertexBuffer = createBufferWithData(device, { size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX }, vertexData.buffer); |
| |
| const context = canvas.getContext("gpu"); |
| const swapChain = context.configureSwapChain({ device: device, format: "bgra8unorm" }); |
| const colorAttachment = { |
| attachment: swapChain.getCurrentTexture().createDefaultView(), |
| loadOp: "clear", |
| storeOp: "store", |
| clearColor: { r: 0, g: 0, b: 0, a: 0 } |
| }; |
| |
| const commandEncoder = device.createCommandEncoder(); |
| const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [colorAttachment] }); |
| passEncoder.setPipeline(pipeline); |
| passEncoder.setVertexBuffers(0, [vertexBuffer], [0]); |
| passEncoder.draw(4, 1, 0, 0); |
| passEncoder.draw(4, 1, 0, 0); |
| passEncoder.endPass(); |
| |
| device.getQueue().submit([commandEncoder.finish()]); |
| } |
| |
| getBasicDevice().then(function(device) { |
| start(device).then(function() { |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| }, function() { |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| }); |
| }, function() { |
| drawGreenSquareInSoftware(canvas); |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| }); |
| </script> |