| <!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] --> |
| <meta charset=utf-8> |
| <title>Tests for createBufferMapped and mapReadAsync on a GPUBuffer.</title> |
| <body> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script src="js/webgpu-functions.js"></script> |
| <script> |
| async function runTests() { |
| const device = await getBasicDevice(); |
| |
| // Basic mapReadAsync functionality |
| promise_test(async () => { |
| const buffer = device.createBuffer({ size: 16, usage: GPUBufferUsage.MAP_READ }); |
| assert_true(buffer instanceof GPUBuffer, "createBuffer returned a GPUBuffer"); |
| |
| let arrayBuffer = await buffer.mapReadAsync(); |
| assert_true(arrayBuffer instanceof ArrayBuffer, "first mapReadAsync resolved successfully"); |
| |
| const readArray = new Float32Array(arrayBuffer); |
| assert_equals(readArray[0], 0, "successfully access a value from a map read"); |
| |
| buffer.unmap(); |
| |
| const promise = buffer.mapReadAsync(); // This will eventually reject due to buffer.destroy() |
| |
| buffer.destroy(); |
| |
| await promise.then(() => { |
| assert_unreached("Buffer was destroyed!"); |
| }, () => {}); |
| |
| }, "mapReadAsync, unmap, and destroy on a GPUBuffer."); |
| |
| // GPUDevice.createBufferMapped |
| promise_test(async () => { |
| const bufferResult = device.createBufferMapped({ size: 16, usage: GPUBufferUsage.MAP_READ }); |
| const buffer = bufferResult[0]; |
| const arrayBuffer = bufferResult[1]; |
| |
| assert_true(buffer instanceof GPUBuffer, "createBufferMapped returned a GPUBuffer"); |
| assert_true(arrayBuffer instanceof ArrayBuffer, "createBufferMapped returned an ArrayBuffer"); |
| |
| let array = new Float32Array(arrayBuffer); |
| array.set([1, 2, 3, 4]); |
| |
| // Buffer should already be "mapped". |
| await buffer.mapReadAsync().then(() => { |
| assert_unreached("GPUBuffer created via GPUBufferMapped cannot be mapped until after first unmap!"); |
| }, () => {}); |
| |
| buffer.unmap(); |
| |
| // Buffer should not be re-mappable for writes. |
| await buffer.mapWriteAsync().then(() => { |
| assert_unreached("Buffer was not created with MAP_WRITE!"); |
| }, () => {}); |
| |
| // Read results of original writes. |
| let resultArrayBuffer = await buffer.mapReadAsync(); |
| const resultArray = new Float32Array(resultArrayBuffer); |
| resultArray.forEach((v, i) => { |
| assert_equals(v, array[i], "Successfully map-read value written to GPUBuffer mapped on creation"); |
| }) |
| |
| buffer.destroy(); |
| }, "GPUBuffer.mapReadAsync on a buffer created via GPUDevice.createBufferMapped."); |
| |
| /* Basic validation */ |
| // FIXME: Test invalid combinations of GPUBufferUsage after implementing error handling. |
| |
| promise_test(async () => { |
| const buffer = device.createBuffer({ size: 16, usage: GPUBufferUsage.MAP_WRITE }); |
| |
| await buffer.mapReadAsync().then(() => { |
| assert_unreached("Buffer was not created with MAP_READ!"); |
| }, () => {}); |
| }, "Reject a map read on a buffer not created with MAP_READ usage."); |
| |
| /* Extended unmap/destroy and promise settling testing */ |
| |
| promise_test(async () => { |
| const buffer = device.createBuffer({ size: 16, usage: GPUBufferUsage.MAP_READ }); |
| |
| buffer.mapReadAsync().then(() => { |
| buffer.unmap(); |
| }, () => { |
| assert_unreached(); |
| }); |
| |
| await buffer.mapReadAsync().then(() => { |
| assert_unreached("Map operation was invalid!"); // buffer was still in mapped state during promise creation |
| }, () => {}); |
| }, "Reject a map read on a mapped GPUBuffer."); |
| |
| promise_test(async () => { |
| const buffer = device.createBuffer({ size: 16, usage: GPUBufferUsage.MAP_READ }); |
| |
| const promise = buffer.mapReadAsync(); |
| buffer.unmap(); |
| |
| await promise.then(() => { |
| assert_unreached("Buffer was unmapped!"); // buffer was unmapped, which rejects pending promises |
| },() => {}); |
| }, "Reject a pending map read if GPUBuffer is unmapped."); |
| } |
| |
| runTests(); |
| </script> |
| </body> |