diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /dom/webgpu/mochitest | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/webgpu/mochitest')
17 files changed, 668 insertions, 0 deletions
diff --git a/dom/webgpu/mochitest/mochitest-no-pref.ini b/dom/webgpu/mochitest/mochitest-no-pref.ini new file mode 100644 index 0000000000..c1e2681367 --- /dev/null +++ b/dom/webgpu/mochitest/mochitest-no-pref.ini @@ -0,0 +1,4 @@ +[DEFAULT] +subsuite = webgpu + +[test_disabled.html] diff --git a/dom/webgpu/mochitest/mochitest.ini b/dom/webgpu/mochitest/mochitest.ini new file mode 100644 index 0000000000..3bd5124a21 --- /dev/null +++ b/dom/webgpu/mochitest/mochitest.ini @@ -0,0 +1,32 @@ +[DEFAULT] +subsuite = webgpu +run-if = !release_or_beta +prefs = + dom.webgpu.enabled=true + gfx.offscreencanvas.enabled=true +support-files = + worker_wrapper.js + test_basic_canvas.worker.js + test_submit_render_empty.worker.js + +[test_enabled.html] +[test_basic_canvas.worker.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_device_creation.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_buffer_mapping.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_command_buffer_creation.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_submit_compute_empty.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_submit_render_empty.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_submit_render_empty.worker.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_queue_copyExternalImageToTexture.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_queue_write.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') +[test_error_scope.html] +fail-if = (os == 'linux' && os_version == '18.04') || (os == 'win' && os_version == '6.1') diff --git a/dom/webgpu/mochitest/test_basic_canvas.worker.html b/dom/webgpu/mochitest/test_basic_canvas.worker.html new file mode 100644 index 0000000000..f34ef8af24 --- /dev/null +++ b/dom/webgpu/mochitest/test_basic_canvas.worker.html @@ -0,0 +1,20 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="worker_wrapper.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<canvas id="canvas"></canvas> +<script> + +const canvas = document.getElementById("canvas"); +const offscreen = canvas.transferControlToOffscreen(); + +runWorkerTest('test_basic_canvas.worker.js', {offscreen}, [offscreen]); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_basic_canvas.worker.js b/dom/webgpu/mochitest/test_basic_canvas.worker.js new file mode 100644 index 0000000000..ddbc15c512 --- /dev/null +++ b/dom/webgpu/mochitest/test_basic_canvas.worker.js @@ -0,0 +1,32 @@ +self.addEventListener("message", async function(event) { + try { + const offscreen = event.data.offscreen; + const context = offscreen.getContext("webgpu"); + + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const swapChainFormat = context.getPreferredFormat(adapter); + + context.configure({ + device, + format: swapChainFormat, + size: { width: 100, height: 100, depth: 1 }, + }); + + const texture = context.getCurrentTexture(); + + self.postMessage([ + { + value: texture !== undefined, + message: "texture !== undefined", + }, + ]); + } catch (e) { + self.postMessage([ + { + value: false, + message: "Unhandled exception " + e, + }, + ]); + } +}); diff --git a/dom/webgpu/mochitest/test_buffer_mapping.html b/dom/webgpu/mochitest/test_buffer_mapping.html new file mode 100644 index 0000000000..a3f59d0caf --- /dev/null +++ b/dom/webgpu/mochitest/test_buffer_mapping.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +async function testBody() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + const bufferRead = device.createBuffer({ size:4, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST }); + const bufferWrite = device.createBuffer({ size:4, usage: GPUBufferUsage.COPY_SRC, mappedAtCreation: true }); + (new Float32Array(bufferWrite.getMappedRange())).set([1.0]); + bufferWrite.unmap(); + + const encoder = device.createCommandEncoder(); + encoder.copyBufferToBuffer(bufferWrite, 0, bufferRead, 0, 4); + device.queue.submit([encoder.finish()]); + + await bufferRead.mapAsync(GPUMapMode.READ); + + try { + bufferRead.getMappedRange(0, 5); + ok(false, 'mapped with size outside buffer should throw'); + } catch(e) { + ok(true, 'mapped with size outside buffer should throw OperationError'); + } + + try { + bufferRead.getMappedRange(4, 1); + ok(false, 'mapped with offset outside buffer should throw'); + } catch(e) { + ok(true, 'mapped with offset outside buffer should throw OperationError'); + } + + const data = bufferRead.getMappedRange(); + is(data.byteLength, 4, 'array should be 4 bytes long'); + + const value = (new Float32Array(data))[0]; + ok(value == 1.0, 'value == 1.0'); + + bufferRead.unmap(); + is(data.byteLength, 0, 'array should be detached after explicit unmap'); +}; + +SimpleTest.waitForExplicitFinish(); +testBody() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_command_buffer_creation.html b/dom/webgpu/mochitest/test_command_buffer_creation.html new file mode 100644 index 0000000000..e4f7356e0a --- /dev/null +++ b/dom/webgpu/mochitest/test_command_buffer_creation.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const encoder = device.createCommandEncoder(); + const command_buffer = encoder.finish(); + ok(command_buffer !== undefined, 'command_buffer !== undefined'); +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_device_creation.html b/dom/webgpu/mochitest/test_device_creation.html new file mode 100644 index 0000000000..8e14ac2760 --- /dev/null +++ b/dom/webgpu/mochitest/test_device_creation.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const limits = adapter.limits; + const features = adapter.features; + const device = await adapter.requestDevice(); + ok(device !== undefined, 'device !== undefined'); +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_disabled.html b/dom/webgpu/mochitest/test_disabled.html new file mode 100644 index 0000000000..e96b8d7ecf --- /dev/null +++ b/dom/webgpu/mochitest/test_disabled.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(!SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be disabled.'); +ok(navigator.gpu === undefined, 'navigator.gpu === undefined'); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_enabled.html b/dom/webgpu/mochitest/test_enabled.html new file mode 100644 index 0000000000..3f4af2177b --- /dev/null +++ b/dom/webgpu/mochitest/test_enabled.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); +ok(navigator.gpu !== undefined, 'navigator.gpu !== undefined'); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_error_scope.html b/dom/webgpu/mochitest/test_error_scope.html new file mode 100644 index 0000000000..c59996d39e --- /dev/null +++ b/dom/webgpu/mochitest/test_error_scope.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + device.pushErrorScope("validation"); + const buffer = device.createBuffer({ size:0, usage: 0 }); + const error = await device.popErrorScope(); + + isnot(error, null) + + try { + await device.popErrorScope(); + ok(false, "Should have thrown") + } catch (ex) { + ok(ex.name == 'OperationError', "Should throw an OperationError") + } +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_queue_copyExternalImageToTexture.html b/dom/webgpu/mochitest/test_queue_copyExternalImageToTexture.html new file mode 100644 index 0000000000..0224620e85 --- /dev/null +++ b/dom/webgpu/mochitest/test_queue_copyExternalImageToTexture.html @@ -0,0 +1,181 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset='utf-8'> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> + +<body> + <script type='text/javascript'> +'use strict'; + +ok( + SpecialPowers.getBoolPref("dom.webgpu.enabled"), + "WebGPU pref should be enabled." +); +ok( + SpecialPowers.getBoolPref("gfx.offscreencanvas.enabled"), + "OffscreenCanvas pref should be enabled." +); + +SimpleTest.waitForExplicitFinish(); + +function requestAnimationFramePromise() { + return new Promise(requestAnimationFrame); +} + +function createSourceCanvasWebgl() { + const offscreenCanvas = new OffscreenCanvas(200, 200); + const gl = offscreenCanvas.getContext("webgl"); + + const COLOR_VALUE = 127.0 / 255.0; + const ALPHA_VALUE = 127.0 / 255.0; + + gl.enable(gl.SCISSOR_TEST); + + gl.scissor(0, 0, 100, 100); + gl.clearColor(COLOR_VALUE, 0.0, 0.0, ALPHA_VALUE); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.scissor(100, 0, 100, 100); + gl.clearColor(0.0, COLOR_VALUE, 0.0, ALPHA_VALUE); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.scissor(0, 100, 100, 100); + gl.clearColor(0.0, 0.0, COLOR_VALUE, ALPHA_VALUE); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.scissor(100, 100, 100, 100); + gl.clearColor(0.0, 0.0, 0.0, ALPHA_VALUE); + gl.clear(gl.COLOR_BUFFER_BIT); + + return { + source: offscreenCanvas, + origin: { x: 0, y: 0 }, + flipY: true, + }; +} + +function createSourceCanvas2d() { + const offscreenCanvas = new OffscreenCanvas(200, 200); + const context = offscreenCanvas.getContext("2d"); + + context.fillStyle = "rgba(255,0,0,0.498)"; + context.fillRect(0, 0, 100, 100); + + context.fillStyle = "rgba(0,255,0,0.498)"; + context.fillRect(100, 0, 100, 100); + + context.fillStyle = "rgba(0,0,255,0.498)"; + context.fillRect(0, 100, 100, 100); + + context.fillStyle = "rgba(0,0,0,0.498)"; + context.fillRect(100, 100, 100, 100); + + return { + source: offscreenCanvas, + origin: { x: 0, y: 0 }, + flipY: false, + }; +} + +function createSourceImageBitmap() { + const sourceCanvas = createSourceCanvas2d(); + return { + source: sourceCanvas.source.transferToImageBitmap(), + origin: { x: 0, y: 0 }, + flipY: false, + }; +} + +async function mapDestTexture(device, source, destFormat, premultiply, copySize) { + const bytesPerRow = 256 * 4; // 256 aligned for 200 pixels + const texture = device.createTexture({ + format: destFormat, + size: copySize, + usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST, + }); + + device.queue.copyExternalImageToTexture( + source, + { texture, premultipliedAlpha: premultiply }, + copySize, + ); + + const buffer = device.createBuffer({ + size: 1024 * 200, + usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST, + }); + + const encoder = device.createCommandEncoder(); + encoder.copyTextureToBuffer( + { texture }, + { buffer, bytesPerRow }, + copySize, + ); + device.queue.submit([encoder.finish()]); + + await buffer.mapAsync(GPUMapMode.READ); + return buffer; +} + +async function verifyBuffer(test, device, source, format, premultiply, copyDim, topLeftPixelData) { + try { + const buffer = await mapDestTexture(device, source, format, premultiply, copyDim); + const arrayBuffer = buffer.getMappedRange(); + const view = new Uint8Array(arrayBuffer); + for (let i = 0; i < topLeftPixelData.length; ++i) { + is(view[i], topLeftPixelData[i], test + " " + format + " (" + source.origin.x + "," + source.origin.y + ") channel " + i); + } + } catch(e) { + ok(false, "WebGPU exception: " + e); + } +} + +async function verifySourceCanvas(test, device, source) { + await verifyBuffer(test, device, source, "rgba8unorm", /* premultiply */ true, { width: 200, height: 200 }, [127, 0, 0, 127]); + await verifyBuffer(test, device, source, "bgra8unorm", /* premultiply */ true, { width: 200, height: 200 }, [0, 0, 127, 127]); + await verifyBuffer(test, device, source, "rgba8unorm", /* premultiply */ false, { width: 200, height: 200 }, [255, 0, 0, 127]); + await verifyBuffer(test, device, source, "bgra8unorm", /* premultiply */ false, { width: 200, height: 200 }, [0, 0, 255, 127]); + + // The copy is flipped but the origin is relative to the original source data, + // so we need to invert for WebGL. + const topRightPixelData = test === "webgl" ? [0, 0, 0, 127] : [0, 127, 0, 127]; + const topRightOrigin = { origin: { x: 100, y: 0 } }; + await verifyBuffer(test, device, { ...source, ...topRightOrigin }, "bgra8unorm", /* premultiply */ true, { width: 100, height: 100 }, topRightPixelData); + + const bottomLeftPixelData = test === "webgl" ? [0, 0, 127, 127] : [127, 0, 0, 127]; + const bottomLeftOrigin = { origin: { x: 0, y: 100 } }; + await verifyBuffer(test, device, { ...source, ...bottomLeftOrigin }, "bgra8unorm", /* premultiply */ true, { width: 100, height: 100 }, bottomLeftPixelData); +} + +async function writeDestCanvas(source2d, sourceWebgl, sourceImageBitmap) { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + await verifySourceCanvas("2d", device, source2d); + await verifySourceCanvas("imageBitmap", device, sourceImageBitmap); + await verifySourceCanvas("webgl", device, sourceWebgl); +} + +async function runTest() { + try { + const source2d = createSourceCanvas2d(); + const sourceWebgl = createSourceCanvasWebgl(); + const sourceImageBitmap = createSourceImageBitmap(); + await requestAnimationFramePromise(); + await requestAnimationFramePromise(); + await writeDestCanvas(source2d, sourceWebgl, sourceImageBitmap); + } catch(e) { + ok(false, "Uncaught exception: " + e); + } finally { + SimpleTest.finish(); + } +} + +runTest(); + </script> +</body> + +</html> diff --git a/dom/webgpu/mochitest/test_queue_write.html b/dom/webgpu/mochitest/test_queue_write.html new file mode 100644 index 0000000000..bcc8a104df --- /dev/null +++ b/dom/webgpu/mochitest/test_queue_write.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const buffer = device.createBuffer({size:16, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | GPUBufferUsage.VERTEX}); + const arrayBuf = new ArrayBuffer(16); + (new Int32Array(arrayBuf)).fill(5) + device.queue.writeBuffer(buffer, 0, arrayBuf, 0); + const texture = device.createTexture({size: [2,2,1], dimension: "2d", format: "rgba8unorm", usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC }); + device.queue.writeTexture({ texture }, arrayBuf, { bytesPerRow:8 }, [2,2,1]); + // this isn't a process check, we need to read back the contents and verify the writes happened + ok(device !== undefined, ''); +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_submit_compute_empty.html b/dom/webgpu/mochitest/test_submit_compute_empty.html new file mode 100644 index 0000000000..e5a9eabfc1 --- /dev/null +++ b/dom/webgpu/mochitest/test_submit_compute_empty.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + const encoder = device.createCommandEncoder(); + const pass = encoder.beginComputePass(); + pass.endPass(); + const command_buffer = encoder.finish(); + device.queue.submit([command_buffer]); + ok(command_buffer !== undefined, 'command_buffer !== undefined'); +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_submit_render_empty.html b/dom/webgpu/mochitest/test_submit_render_empty.html new file mode 100644 index 0000000000..aec2a606ef --- /dev/null +++ b/dom/webgpu/mochitest/test_submit_render_empty.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +ok(SpecialPowers.getBoolPref('dom.webgpu.enabled'), 'Pref should be enabled.'); + +const func = async function() { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + const swapChainFormat = "rgba8unorm"; + const bundleEncoder = device.createRenderBundleEncoder({ + colorFormats: [swapChainFormat], + }); + const bundle = bundleEncoder.finish({}); + + const texture = device.createTexture({ + size: { width: 100, height: 100, depth: 1 }, + format: swapChainFormat, + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); + const view = texture.createView(); + + const encoder = device.createCommandEncoder(); + const pass = encoder.beginRenderPass({ + colorAttachments: [{ + view, + loadValue: { r: 0, g: 0, b: 0, a: 0 }, + storeOp: "store", + }], + }); + pass.executeBundles([bundle]); + pass.endPass(); + const command_buffer = encoder.finish(); + + device.queue.submit([command_buffer]); + ok(command_buffer !== undefined, 'command_buffer !== undefined'); +}; + +SimpleTest.waitForExplicitFinish(); +func() + .catch((e) => ok(false, "Unhandled exception " + e)) + .finally(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_submit_render_empty.worker.html b/dom/webgpu/mochitest/test_submit_render_empty.worker.html new file mode 100644 index 0000000000..100f866ecc --- /dev/null +++ b/dom/webgpu/mochitest/test_submit_render_empty.worker.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset='utf-8'> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<script src="worker_wrapper.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +runWorkerTest('test_submit_render_empty.worker.js', {}, []); + +</script> +</body> +</html> diff --git a/dom/webgpu/mochitest/test_submit_render_empty.worker.js b/dom/webgpu/mochitest/test_submit_render_empty.worker.js new file mode 100644 index 0000000000..1d922d38d5 --- /dev/null +++ b/dom/webgpu/mochitest/test_submit_render_empty.worker.js @@ -0,0 +1,48 @@ +self.addEventListener("message", async function(event) { + try { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + + const swapChainFormat = "rgba8unorm"; + const bundleEncoder = device.createRenderBundleEncoder({ + colorFormats: [swapChainFormat], + }); + const bundle = bundleEncoder.finish({}); + + const texture = device.createTexture({ + size: { width: 100, height: 100, depth: 1 }, + format: swapChainFormat, + usage: GPUTextureUsage.RENDER_ATTACHMENT, + }); + const view = texture.createView(); + + const encoder = device.createCommandEncoder(); + const pass = encoder.beginRenderPass({ + colorAttachments: [ + { + view, + loadValue: { r: 0, g: 0, b: 0, a: 0 }, + storeOp: "store", + }, + ], + }); + pass.executeBundles([bundle]); + pass.endPass(); + const command_buffer = encoder.finish(); + + device.queue.submit([command_buffer]); + self.postMessage([ + { + value: command_buffer !== undefined, + message: "command_buffer !== undefined", + }, + ]); + } catch (e) { + self.postMessage([ + { + value: false, + message: "Unhandled exception " + e, + }, + ]); + } +}); diff --git a/dom/webgpu/mochitest/worker_wrapper.js b/dom/webgpu/mochitest/worker_wrapper.js new file mode 100644 index 0000000000..19ce6dd21e --- /dev/null +++ b/dom/webgpu/mochitest/worker_wrapper.js @@ -0,0 +1,33 @@ +ok( + SpecialPowers.getBoolPref("dom.webgpu.enabled"), + "WebGPU pref should be enabled." +); +ok( + SpecialPowers.getBoolPref("gfx.offscreencanvas.enabled"), + "OffscreenCanvas pref should be enabled." +); +SimpleTest.waitForExplicitFinish(); + +const workerWrapperFunc = async function(worker_path, data, transfer) { + const worker = new Worker(worker_path); + + const results = new Promise((resolve, reject) => { + worker.addEventListener("message", event => { + resolve(event.data); + }); + }); + + worker.postMessage(data, transfer); + for (const result of await results) { + ok(result.value, result.message); + } +}; + +async function runWorkerTest(worker_path, data, transfer) { + try { + await workerWrapperFunc(worker_path, data, transfer); + } catch (e) { + ok(false, "Unhandled exception " + e); + } + SimpleTest.finish(); +} |