| <!-- 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> |
| |