<!DOCTYPE html>
<html>
<head>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const shaderSource = `
vertex float4 vertexShader(float4 position : attribute(0), float i : attribute(1)) : SV_Position {
    return position;
}

fragment float4 fragmentShader(float4 position : SV_Position) : SV_Target 0 {
    return position;
}
`;
async function start() {
    const adapter = await navigator.gpu.requestAdapter();
    const device = await adapter.requestDevice();

    const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
    const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
    const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
    const primitiveTopology = "triangle-strip";
    const rasterizationState = {frontFace: "cw", cullMode: "none"};
    const alphaBlend = {};
    const colorBlend = {};
    const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL
    const depthStencilState = null;
    
    const attribute0 = {shaderLocation: 0, format: "float4"};
    const attribute1 = {shaderLocation: 1, format: "float"};
    const input0 = {stride: 16, attributeSet: [attribute0]};
    const input1 = {stride: 4, attributeSet: [attribute1]};
    const inputs = [input0, input1];
    const vertexInput = {vertexBuffers: inputs};

    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]};
    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);

    const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
    const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);

    const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
    const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor);
    const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync();
    const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer);
    vertexBuffer0Float32Array[0] = -0.5;
    vertexBuffer0Float32Array[1] = -0.5;
    vertexBuffer0Float32Array[2] = 1.0;
    vertexBuffer0Float32Array[3] = 1;
    vertexBuffer0Float32Array[4] = -0.5;
    vertexBuffer0Float32Array[5] = 0.5;
    vertexBuffer0Float32Array[6] = 1.0;
    vertexBuffer0Float32Array[7] = 1;
    vertexBuffer0Float32Array[8] = 0.5;
    vertexBuffer0Float32Array[9] = -0.5;
    vertexBuffer0Float32Array[10] = 1.0;
    vertexBuffer0Float32Array[11] = 1;
    vertexBuffer0Float32Array[12] = 0.5;
    vertexBuffer0Float32Array[13] = 0.5;
    vertexBuffer0Float32Array[14] = 1.0;
    vertexBuffer0Float32Array[15] = 1;
    vertexBuffer0.unmap();

    const vertexBuffer1Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
    const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor);
    const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync();
    const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer);
    vertexBuffer1Float32Array[0] = 1;
    vertexBuffer1Float32Array[1] = 1;
    vertexBuffer1Float32Array[2] = 1;
    vertexBuffer1Float32Array[3] = 1;
    vertexBuffer1.unmap();

    const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
    const resourceBuffer = device.createBuffer(resourceBufferDescriptor);
    const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync();
    const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer);
    resourceBufferFloat32Array[0] = 1;
    resourceBuffer.unmap();

    const bufferBinding = {buffer: resourceBuffer, size: 4};
    const bindGroupBinding = {binding: 0, resource: bufferBinding};
    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
    const bindGroup = device.createBindGroup(bindGroupDescriptor);

    const canvas = document.getElementById("canvas");
    const context = canvas.getContext("gpu");
    const swapChainDescriptor = {device, format: "bgra8unorm"};
    const swapChain = context.configureSwapChain(swapChainDescriptor);
    const outputTexture = swapChain.getCurrentTexture();
    const outputTextureView = outputTexture.createDefaultView();

    const commandEncoder = device.createCommandEncoder(); // {}
    const red = {r: 0, g: 0, b: 1, a: 1};
    const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor: red}];
    const depthStencilAttachment = null;
    const renderPassDescriptor = {colorAttachments, depthStencilAttachment};
    const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
    renderPassEncoder.setPipeline(renderPipeline);
    renderPassEncoder.setBindGroup(0, bindGroup);
    renderPassEncoder.setVertexBuffers(0, [vertexBuffer0, vertexBuffer1], [0, 0]);
    renderPassEncoder.draw(4, 1, 0, 0);
    renderPassEncoder.endPass();
    const commandBuffer = commandEncoder.finish();
    device.getQueue().submit([commandBuffer]);
}
if (window.testRunner)
    testRunner.waitUntilDone();
window.addEventListener("load", function() {
    start().then(function() {
        if (window.testRunner)
            testRunner.notifyDone();
    }, function() {
        if (window.testRunner)
            testRunner.notifyDone();
    });
});
</script>
</body>
</html>
