<!-- webkit-test-runner [ enableMetalShaderValidation=true ] -->
<script src="../../../resources/js-test-pre.js"></script>
<script>
async function run() {
    let adapter = await navigator.gpu.requestAdapter();
    let device = await adapter.requestDevice();
    let bindGroupLayout = device.createBindGroupLayout({
        entries: [
            { binding: 1, visibility: GPUShaderStage.VERTEX, externalTexture: {} },
            { binding: 2, visibility: GPUShaderStage.VERTEX, buffer: {} },
        ]
    });
    let pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
    let shaderModule1 = device.createShaderModule({ code: `
    @group(0) @binding(2) var<uniform> buffer1: mat2x3h;
    struct VertexOutput0 {
        @location(0) @interpolate(flat) f0: i32,
        @builtin(position) f1: vec4f,
        @location(2) f2: vec4f
    }
    fn unconst_u32(v: u32) -> u32 { return v; }
    @vertex fn vertex0() -> VertexOutput0 {
        var out: VertexOutput0;
        out = VertexOutput0(
            0,
            vec4f(buffer1[unconst_u32(0)].zxxy),
            vec4f(buffer1[unconst_u32(0)].zxxy)
        );
        return out;
    }
    `});
    let shaderModule2 = device.createShaderModule({ code: `
    struct FragmentOutput1 {
        @location(0) f0: vec4u,
        @location(1) f1: vec4f,
    }
    @fragment fn fragment1() -> FragmentOutput1 {
        var out: FragmentOutput1;
        return out;
    }
    `});
    let pipeline = device.createRenderPipeline({
        layout: pipelineLayout,
        fragment: {
            module: shaderModule2,
            targets: [
                { format: 'rg32uint', writeMask: GPUColorWrite.ALL },
                { format: 'rg16float', writeMask: GPUColorWrite.ALL },
            ]
        },
        vertex: {
            module: shaderModule1,
            buffers: [
                { arrayStride: 0, attributes: [{ format: 'sint32x2', offset: 0, shaderLocation: 2 }] },
            ]
        }
    });
    let texture1 = device.createTexture({ size: [1, 1], format: 'rg16float', usage: GPUTextureUsage.RENDER_ATTACHMENT });
    let texture2 = device.createTexture({ size: [1, 1], format: 'rg32uint', usage: GPUTextureUsage.RENDER_ATTACHMENT });
    let textureView1 = texture1.createView();
    let textureView2 = texture2.createView();
    let videoFrame = new VideoFrame(new ArrayBuffer(16), { codedWidth: 2, codedHeight: 2, format: 'BGRA', timestamp: 0 });
    let externalTexture = device.importExternalTexture({ source: videoFrame });
    let commandEncoder = device.createCommandEncoder();
    let buffer1 = device.createBuffer({ size: 16, usage: GPUBufferUsage.UNIFORM });
    let buffer2 = device.createBuffer({ size: 8, usage: GPUBufferUsage.VERTEX });
    let bindGroup = device.createBindGroup({
        layout: bindGroupLayout,
        entries: [
            { binding: 1, resource: externalTexture },
            { binding: 2, resource: { buffer: buffer1 } },
        ]
    });
    let renderPassEncoder = commandEncoder.beginRenderPass({
        colorAttachments: [
            { view: textureView2, loadOp: 'clear', storeOp: 'discard' },
            { view: textureView1, loadOp: 'clear', storeOp: 'discard' },
        ]
    });
    renderPassEncoder.setBindGroup(0, bindGroup);
    renderPassEncoder.setPipeline(pipeline);
    renderPassEncoder.setVertexBuffer(0, buffer2)
    renderPassEncoder.draw(3);
    renderPassEncoder.end();
    let commandBuffer = commandEncoder.finish();
    device.queue.submit([commandBuffer]);
    await device.queue.onSubmittedWorkDone();
    debug('Pass')
    globalThis.testRunner?.notifyDone();
}

globalThis.testRunner?.dumpAsText();
globalThis.testRunner?.waitUntilDone();

run();
</script>

