blob: 321001a2e3203a9c92a4c2dcc711504710a7f5d8 [file]
<!-- webkit-test-runner [ enableMetalShaderValidation=true ] -->
<style>
:root { background: #102030e0; color: #99ddbbcc; font-size: 15px; }
</style>
<script src="../../../resources/js-test-pre.js"></script>
<script id="shared">
const log = console.log;
async function gc() {
await 0;
if (globalThis.GCController) {
globalThis.GCController.collect();
} else if (globalThis.$vm) {
globalThis.$vm.gc();
} else {
log('no GC available');
}
}
/**
* @param {GPUDevice} device
* @param {GPUComputePassEncoder} computePassEncoder
*/
function clearResourceUsages(device, computePassEncoder) {
let code = `@compute @workgroup_size(1) fn c() {}`;
let module = device.createShaderModule({code});
computePassEncoder.setPipeline(device.createComputePipeline(
{
layout: 'auto',
compute: {module},
}));
computePassEncoder.dispatchWorkgroups(1);
}
/**
* @template {any} T
* @param {GPUDevice} device
* @param {string} label
* @param {()=>T} payload
* @returns {Promise<T>}
*/
async function validationWrapper(device, label, payload) {
device.pushErrorScope('internal');
device.pushErrorScope('out-of-memory');
device.pushErrorScope('validation');
let result = payload();
let validationError = await device.popErrorScope();
let outOfMemoryError = await device.popErrorScope();
let internalError = await device.popErrorScope();
let error = validationError ?? outOfMemoryError ?? internalError;
if (error) {
log('*'.repeat(25));
log(error[Symbol.toStringTag]);
log(error.message);
log(label);
if (error.stack != `_`) {
log(error.stack);
}
log(location);
log('*'.repeat(25));
throw error;
}
return result;
}
const videoUrls = [
];
/**
* @param {number} index
* @returns {Promise<HTMLVideoElement>}
*/
function videoWithData(index) {
let video = document.createElement('video');
video.src = videoUrls[index % videoUrls.length];
return new Promise(resolve => {
video.onloadeddata = () => {
resolve(video);
};
});
}
/**
* @returns {Promise<string>}
*/
async function makeDataUrl(width, height, color0, color1) {
let offscreenCanvas = new OffscreenCanvas(width, height);
let ctx = offscreenCanvas.getContext('2d');
let gradient = ctx.createLinearGradient(0, 0, width, height);
gradient.addColorStop(0, color0);
gradient.addColorStop(0.1, color1);
gradient.addColorStop(0.3, color0);
gradient.addColorStop(0.7, color1);
gradient.addColorStop(0.9, color0);
gradient.addColorStop(1, color1);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
let blob = await offscreenCanvas.convertToBlob();
let fileReader = new FileReader();
fileReader.readAsDataURL(blob);
return new Promise(resolve => {
fileReader.onload = () => {
resolve(fileReader.result);
};
});
}
async function imageWithData(width, height, color0, color1) {
let dataUrl = await makeDataUrl(width, height, color0, color1);
let img = document.createElement('img');
img.src = dataUrl;
await img.decode();
return img;
}
/**
* @param {string} payload
* @returns {string}
*/
function toBlobUrl(payload) {
let blob = new Blob([payload], {type: 'text/javascript'});
return URL.createObjectURL(blob);
}
</script>
<script>
globalThis.testRunner?.dumpAsText();
globalThis.testRunner?.waitUntilDone();
async function window0() {
// START
c = await navigator.gpu.requestAdapter();
device0 = await c.requestDevice();
texture1 = device0.createTexture({
size : [],
dimension : '1d',
format : 'rgba16sint',
usage : GPUTextureUsage.STORAGE_BINDING | []
});
veryExplicitBindGroupLayout1 = device0.createBindGroupLayout({
entries : [
{
binding : 15,
visibility : GPUShaderStage | GPUShaderStage,
storageTexture : {format : 'rgba16sint', viewDimension : '1d'}
},
{binding : 31, visibility : GPUShaderStage.VERTEX, externalTexture : {}},
{binding : 63, visibility : GPUShaderStage.FRAGMENT, externalTexture : {}},
{
binding : 138,
visibility : GPUShaderStage.FRAGMENT,
buffer : {type : 'storage', hasDynamicOffset : true}
},
{
binding : 141,
visibility : GPUShaderStage.FRAGMENT,
buffer : {type : 'storage'}
}
]
})
textureView2 = texture1.createView()
d = device0.createShaderModule({
code : `
fn unconst_u32(f: u32) -> u32 {
return f;
}
@group(0) @binding(141) var<storage, read_write> buffer3: array<array<atomic<u32>, 7>>;
@vertex fn vertex0(@location(10) h: vec4u, @location(6) a2: vec2i) -> @builtin(position) vec4f {
var i: vec4f;
return i;
}
@fragment fn fragment0() -> @location(200) vec4i {
var i: vec4i;
if bool(atomicExchange(&buffer3[arrayLength(&buffer3)][unconst_u32(8)], 71)) {
}
return i;
}
@compute @workgroup_size(11) fn j() {}
`
})
let texture14 = device0.createTexture({
size : [ 120, 176 ],
format : 'depth16unorm',
usage : GPUTextureUsage.RENDER_ATTACHMENT
})
k = device0.createPipelineLayout(
{bindGroupLayouts : [ veryExplicitBindGroupLayout1 ]});
l = await device0.createRenderPipelineAsync({
layout : k,
fragment : {
module : d,
targets : [ {
format : 'rg16sint',
} ]
},
depthStencil : {
format : 'depth16unorm',
depthWriteEnabled : true,
depthCompare : 'less-equal'
},
vertex : {
module : d,
buffers : [ {
arrayStride : 308,
attributes : [
{format : 'sint8x2', offset : 86, shaderLocation : 6},
{format : 'uint32x4', offset : 8, shaderLocation : 10}
]
} ]
},
primitive : {topology : 'point-list'}
});
n = device0.createTexture({
size : [ 120, 176 ],
format : 'rg16sint',
usage : GPUTextureUsage.RENDER_ATTACHMENT
})
let textureView10 = n.createView();
videoFrame0 = new VideoFrame(new ArrayBuffer(16), {
codedWidth : 2,
codedHeight : 2,
format : 'RGBX',
timestamp : 0})
o = device0.createComputePipeline({
layout : k,
compute : {
module : d,
}
})
p = new VideoFrame(
new ArrayBuffer(16),
{codedWidth : 2, codedHeight : 2, format : 'RGBX', timestamp : 0})
recycledExplicitBindGroupLayout0 = o.getBindGroupLayout({GPUBufferUsage})
shaderModule1 = device0.createShaderModule({
code : ` @compute @workgroup_size(1) fn compute1() {}
`
})
q = device0.createPipelineLayout(
{bindGroupLayouts : [ recycledExplicitBindGroupLayout0 ]})
textureView13 = texture14.createView()
s = device0.createComputePipeline(
{layout : q, compute : {module : shaderModule1}});
recycledExplicitBindGroupLayout1 = s.getBindGroupLayout(0)
commandEncoder28 = device0.createCommandEncoder()
t = device0.createBuffer({size : 33, usage : GPUBufferUsage.STORAGE})
buffer34 = device0.createBuffer({size : 15286, usage : GPUBufferUsage.STORAGE})
externalTexture4 = device0.importExternalTexture({source : videoFrame0})
u = commandEncoder28.beginRenderPass({
colorAttachments : [ {
view : textureView10,
clearValue : {r : 121.6, g : 258.5, b : 159.7, a : 317.9},
loadOp : 'load',
storeOp : 'store'
} ],
depthStencilAttachment :
{view : textureView13, depthLoadOp : 'load', depthStoreOp : 'store'}
})
v = device0.importExternalTexture({source : p})
try {
u.setPipeline(l)
} catch {
}
bindGroup31 = device0.createBindGroup({
layout : recycledExplicitBindGroupLayout1,
entries : [
{binding : 138, resource : {buffer : buffer34, offset : 2048, size : 3644}},
{binding : 141, resource : {buffer : t, size : 28}},
{binding : 31, resource : v}, {binding : 15, resource : textureView2},
{binding : 63, resource : externalTexture4}
]
});
buffer87 = device0.createBuffer({size : 8036, usage : GPUBufferUsage.VERTEX})
try {
u.setBindGroup(0, bindGroup31, [ 768 ])
} catch {
}
try {
u.setVertexBuffer(0, buffer87)
u.draw(1)
} catch {
}
try {
u.end()
} catch {
}
commandBuffer21 = commandEncoder28.finish();
try {
device0.queue.submit([ commandBuffer21 ])
} catch {
}
// END
await device0.queue.onSubmittedWorkDone();
}
onload = async () => {
try {
let sharedScript = document.querySelector('#shared').textContent;
let workers = [
];
let promises = [ window0() ];
debug('promises created');
let results = await Promise.allSettled(promises);
for (let result of results) {
if (result.status === 'rejected') { throw result.reason; }
}
debug('Pass')
} catch (e) {
log('error');
log(e);
log(e[Symbol.toStringTag]);
log(e.stack);
if (e instanceof GPUPipelineError) {
log(`${e} - ${e.reason}`);
} else if (e instanceof DOMException) {
if (e.name === 'OperationError') {
log(e.message);
} else if (e.name === 'InvalidStateError') {
} else {
log(e);
}
} else if (e instanceof GPUValidationError) {
} else if (e instanceof GPUOutOfMemoryError) {
} else if (e instanceof TypeError) {
log(e);
} else {
log('unexpected error type');
log(e);
}
}
globalThis.testRunner?.notifyDone();
};
</script>