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

struct Foo {
    float x;
}

float operator[](Foo f, uint index) {
    return f.x;
}

Foo operator[]=(Foo f, uint index, float x) {
    f.x = x;
    return f;
}

struct Bar {
    Foo z;
}

Foo operator[](Bar b, uint index) {
    return b.z;
}

Bar operator[]=(Bar b, uint index, Foo a) {
    b.z = a;
    return b;
}

struct Baz {
    Bar p;
}

Bar operator[](Baz b, uint index) {
    return b.p;
}

Baz operator[]=(Baz b, uint index, Bar a) {
    b.p = a;
    return b;
}

fragment float4 fragmentShader() : SV_Target 0 {
    Baz b;
    b[2][3][4] = 1.0;
    return float4(b[2][3][4], b[2][3][4], b[2][3][4], 1.0);
}
`;
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 input0 = {stride: 16, attributeSet: [attribute0]};
    const inputs = [input0];
    const vertexInput = {vertexBuffers: inputs};

    const pipelineLayoutDescriptor = {bindGroupLayouts: []};
    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);

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

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

    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.setVertexBuffers(0, [vertexBuffer], [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>
