blob: 68ecfc56ec729b06a555dca1acabfe93ccb327af [file]
<!-- webkit-test-runner [ enableMetalShaderValidation=true ] -->
<script>
globalThis.testRunner?.waitUntilDone();
const log = console.debug;
onload = async () => {
let adapter = await navigator.gpu.requestAdapter({});
let device = await adapter.requestDevice({});
device.pushErrorScope('validation');
let code = `
@group(0) @binding(0) var<storage, read_write> buf: array<u32>;
const moreThanArrayLength = 65;
@vertex
fn v() -> @builtin(position) vec4f {
return vec4();
}
@fragment
fn f() -> @location(0) vec4f {
let maximumValidIndex = arrayLength(&buf) - 1;
let sameAsBoundedIndex = select(moreThanArrayLength, maximumValidIndex, moreThanArrayLength == maximumValidIndex);
loop {
if sameAsBoundedIndex == arrayLength(&buf) {
buf[5] = buf[moreThanArrayLength];
buf[moreThanArrayLength] = 123456789;
buf[2] = 100 + u32(sameAsBoundedIndex > arrayLength(&buf));
buf[3] = 200 + u32(sameAsBoundedIndex == arrayLength(&buf));
buf[4] = 300 + u32(sameAsBoundedIndex < arrayLength(&buf));
buf[0] = sameAsBoundedIndex;
buf[1] = arrayLength(&buf);
break;
}
}
return vec4();
}
`;
let module = device.createShaderModule({code});
let bindGroupLayout0 = device.createBindGroupLayout({
entries: [
{binding: 0, buffer: {type: 'storage'}, visibility: GPUShaderStage.FRAGMENT},
],
});
let pipeline = device.createRenderPipeline({
layout: device.createPipelineLayout({bindGroupLayouts: [bindGroupLayout0]}),
vertex: {
module,
buffers: [],
},
fragment: {module, targets: [{format: 'bgra8unorm'}]},
primitive: {topology: 'point-list'},
});
globalThis.keep = pipeline;
let buffer0 = device.createBuffer({
size: 256, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
});
let laterBuffer0 = device.createBuffer({
size: 4, usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(laterBuffer0, 0, new Uint32Array(1), 0, 1);
await device.queue.onSubmittedWorkDone();
let bindGroup0 = device.createBindGroup({
layout: bindGroupLayout0, entries: [
{binding: 0, resource: {buffer: buffer0}},
],
});
let texture = device.createTexture({format: 'bgra8unorm', size: [1], usage: GPUTextureUsage.RENDER_ATTACHMENT});
let commandEncoder = device.createCommandEncoder();
let renderPassEncoder = commandEncoder.beginRenderPass({
colorAttachments: [{
view: texture.createView(),
clearValue: [0, 0, 0, 0],
loadOp: 'clear', storeOp: 'store',
}],
});
renderPassEncoder.setPipeline(pipeline);
renderPassEncoder.setBindGroup(0, bindGroup0);
renderPassEncoder.draw(1);
renderPassEncoder.end();
device.queue.submit([commandEncoder.finish()]);
await device.queue.onSubmittedWorkDone();
let lostPromiseResult = await device.lost;
log(lostPromiseResult);
let error = await device.popErrorScope();
if (error) {
log(error.message);
} else {
log('no validation error');
}
globalThis.testRunner?.notifyDone();
};
</script>