<!-- 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: 0, visibility: GPUShaderStage.VERTEX, externalTexture: {} }
        ]
    });
    let pipelineLayout = device.createPipelineLayout({ bindGroupLayouts : [bindGroupLayout] })
    let shaderModule = device.createShaderModule({ code: ` 
        @group(0) @binding(0) var externalTexture: texture_external;
        @vertex fn vertexShader() -> @builtin(position) vec4f {
            return textureLoad(externalTexture, vec2u());
        }
        @fragment fn fragmentShader() -> @location(0) vec4i {
            return vec4i();
        }
    `});
    let videoFrame = new VideoFrame(new ArrayBuffer(16), { codedWidth: 2, codedHeight: 2, format: 'BGRA', timestamp: 0 });
    let texture = device.createTexture({ size: [], format: 'rgba16sint', usage: GPUTextureUsage.RENDER_ATTACHMENT });
    let textureView = texture.createView();
    let externalTexture = device.importExternalTexture({ source: videoFrame });
    let commandEncoder = device.createCommandEncoder()
    let renderPass = commandEncoder.beginRenderPass({ colorAttachments: [{ view: textureView, loadOp: 'load', storeOp: 'discard' }] });
    let renderPipeline2 = await device.createRenderPipelineAsync({
        layout: pipelineLayout,
        fragment: { module: shaderModule, targets: [{ format : 'rgba16sint' }] },
        vertex: { module: shaderModule }
    })
    renderPass.setPipeline(renderPipeline2);
    let bindGroup = device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0, resource: externalTexture }] });
    renderPass.setBindGroup(0, bindGroup);
    renderPass.draw(4);
    device.createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 3, resource: externalTexture }] });
    renderPass.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>

