From 5a5bd56660ab007a2a1dc5e2159f1b34ff07a7ee Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Mon, 10 Jun 2024 21:31:42 -0700 Subject: [PATCH] destroy devices in tests --- package-lock.json | 581 +++++++++--------- package.json | 14 +- src/command-encoder.ts | 2 +- test/js/utils.js | 11 + test/tests/binding-mixin-tests.js | 84 ++- test/tests/canvas-context-tests.js | 7 +- test/tests/command-encoder-tests.js | 39 +- test/tests/command-encoder/copy-utils.js | 81 +-- .../copyBufferToBuffer-tests.js | 33 +- .../copyTextureToTexture-tests.js | 24 +- test/tests/compute-pass-tests.js | 33 +- test/tests/device-tests.js | 12 +- test/tests/push-pop-error-tests.js | 19 +- test/tests/render-bundle-tests.js | 11 +- test/tests/render-mixin-tests.js | 230 ++++--- test/tests/render-pass-tests.js | 116 ++-- test/tests/timestamp-tests.js | 42 +- 17 files changed, 622 insertions(+), 717 deletions(-) diff --git a/package-lock.json b/package-lock.json index 64e2a93..7d752f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-typescript": "^11.1.6", "@tsconfig/recommended": "^1.0.6", - "@typescript-eslint/eslint-plugin": "^7.6.0", - "@typescript-eslint/parser": "^7.6.0", - "@webgpu/types": "^0.1.40", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", + "@webgpu/types": "^0.1.42", "eslint": "^8.57.0", "eslint-plugin-html": "^7.1.0", "eslint-plugin-one-variable-per-var": "^0.0.3", @@ -26,10 +26,10 @@ "express": "^4.19.2", "markdown-it": "^13.0.2", "mocha": "^10.4.0", - "puppeteer": "^21.11.0", - "rollup": "^4.14.1", - "servez": "^2.1.4", - "tslib": "^2.6.2", + "puppeteer": "^22.10.0", + "rollup": "^4.18.0", + "servez": "^2.1.6", + "tslib": "^2.6.3", "typedoc": "^0.25.13", "typescript": "^5.4.5" } @@ -320,16 +320,17 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.9.1.tgz", - "integrity": "sha512-PuvK6xZzGhKPvlx3fpfdM2kYY3P/hB1URtK8wA7XUJ6prn6pp22zvJHu48th0SGcHL9SutbPHrFuQgfXTFobWA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", + "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", "dev": true, "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", "progress": "2.0.3", - "proxy-agent": "6.3.1", - "tar-fs": "3.0.4", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", "unbzip2-stream": "1.4.3", "yargs": "17.7.2" }, @@ -337,7 +338,7 @@ "browsers": "lib/cjs/main-cli.js" }, "engines": { - "node": ">=16.3.0" + "node": ">=18" } }, "node_modules/@puppeteer/browsers/node_modules/cliui": { @@ -354,6 +355,33 @@ "node": ">=12" } }, + "node_modules/@puppeteer/browsers/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@puppeteer/browsers/node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -455,9 +483,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz", - "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", "cpu": [ "arm" ], @@ -468,9 +496,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz", - "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", "cpu": [ "arm64" ], @@ -481,9 +509,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz", - "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", "cpu": [ "arm64" ], @@ -494,9 +522,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz", - "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", "cpu": [ "x64" ], @@ -507,9 +535,22 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz", - "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", "cpu": [ "arm" ], @@ -520,9 +561,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz", - "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", "cpu": [ "arm64" ], @@ -533,9 +574,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz", - "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", "cpu": [ "arm64" ], @@ -546,11 +587,11 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz", - "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", "cpu": [ - "ppc64le" + "ppc64" ], "dev": true, "optional": true, @@ -559,9 +600,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz", - "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", "cpu": [ "riscv64" ], @@ -572,9 +613,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz", - "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", "cpu": [ "s390x" ], @@ -585,9 +626,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz", - "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], @@ -598,9 +639,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz", - "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", "cpu": [ "x64" ], @@ -611,9 +652,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz", - "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", "cpu": [ "arm64" ], @@ -624,9 +665,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz", - "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", "cpu": [ "ia32" ], @@ -637,9 +678,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz", - "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", "cpu": [ "x64" ], @@ -667,16 +708,10 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/node": { - "version": "20.12.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.6.tgz", - "integrity": "sha512-3KurE8taB8GCvZBPngVbp0lk5CKi8M9f9k1rsADh0Evdz5SzJ+Q+Hx9uHoFGsLnLnd1xmkDQr2hVhlA0Mn0lKQ==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -697,12 +732,6 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", @@ -714,21 +743,19 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz", - "integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.0.tgz", + "integrity": "sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/type-utils": "7.6.0", - "@typescript-eslint/utils": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.13.0", + "@typescript-eslint/type-utils": "7.13.0", + "@typescript-eslint/utils": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -749,15 +776,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.0.tgz", + "integrity": "sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/scope-manager": "7.13.0", + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/typescript-estree": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", "debug": "^4.3.4" }, "engines": { @@ -777,13 +804,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz", - "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.0.tgz", + "integrity": "sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0" + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -794,13 +821,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz", - "integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.0.tgz", + "integrity": "sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.6.0", - "@typescript-eslint/utils": "7.6.0", + "@typescript-eslint/typescript-estree": "7.13.0", + "@typescript-eslint/utils": "7.13.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -821,9 +848,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz", - "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.0.tgz", + "integrity": "sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -834,13 +861,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz", - "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.0.tgz", + "integrity": "sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/visitor-keys": "7.6.0", + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/visitor-keys": "7.13.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -862,18 +889,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz", - "integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.0.tgz", + "integrity": "sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.6.0", - "@typescript-eslint/types": "7.6.0", - "@typescript-eslint/typescript-estree": "7.6.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.13.0", + "@typescript-eslint/types": "7.13.0", + "@typescript-eslint/typescript-estree": "7.13.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -887,12 +911,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz", - "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.0.tgz", + "integrity": "sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.6.0", + "@typescript-eslint/types": "7.13.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -910,9 +934,9 @@ "dev": true }, "node_modules/@webgpu/types": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.40.tgz", - "integrity": "sha512-/BBkHLS6/eQjyWhY2H7Dx5DHcVrS2ICj9owvSRdgtQT6KcafLZA86tPze0xAOsd4FbsYKCUBUQyNi87q7gV7kw==", + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.42.tgz", + "integrity": "sha512-uvJtt4OD1Vjdebrrz3kNLgpOicYbikwnM8WPG6YD2lkCOHDtPdEtCINJFIFtbOCtPfA8SreR/vKyUNbAt92IwQ==", "dev": true }, "node_modules/accepts": { @@ -1075,12 +1099,51 @@ "dev": true }, "node_modules/bare-events": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", - "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", "dev": true, "optional": true }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.2.tgz", + "integrity": "sha512-az/7TFOh4Gk9Tqs1/xMFq5FuFoeZ9hZ3orsM2x69u8NXVUDXZnpdhG8mZY/Pv6DF954MGn+iIt4rFrG34eQsvg==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1195,12 +1258,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1362,13 +1425,14 @@ } }, "node_modules/chromium-bidi": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.8.tgz", - "integrity": "sha512-blqh+1cEQbHBKmok3rVJkBlBxt9beKBgOsxbFgs7UJcoVbbeZ+K7+6liAsjgpc8l1Xd55cQUy14fXZdGSb4zIw==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.19.tgz", + "integrity": "sha512-UA6zL77b7RYCjJkZBsZ0wlvCTD+jTjllZ8f6wdO4buevXgTZYjV+XLB9CiEa2OuuTGGTLnI7eN9I60YxuALGQg==", "dev": true, "dependencies": { "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0" + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" }, "peerDependencies": { "devtools-protocol": "*" @@ -1502,15 +1566,6 @@ } } }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1629,9 +1684,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1232444", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1232444.tgz", - "integrity": "sha512-pM27vqEfxSxRkTMnF+XCmxSEb6duO5R+t8A9DEEJgy4Wz2RVanje2mmj99B6A3zv2r/qGfYlOvYznUhuokizmg==", + "version": "0.0.1286932", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1286932.tgz", + "integrity": "sha512-wu58HMQll9voDjR4NlPyoDEw1syfzaBNHymMMZ/QOXiHRNluOnDgu9hp1yHOKYoMlxCh4lSSiugLITe6Fvu1eA==", "dev": true }, "node_modules/diff": { @@ -2239,9 +2294,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3141,12 +3196,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3207,12 +3262,6 @@ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "dev": true }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/mocha": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", @@ -3320,26 +3369,6 @@ "node": ">= 0.4.0" } }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -3619,15 +3648,15 @@ } }, "node_modules/proxy-agent": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", - "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", "dev": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.0.1", "proxy-from-env": "^1.1.0", @@ -3663,38 +3692,38 @@ } }, "node_modules/puppeteer": { - "version": "21.11.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-21.11.0.tgz", - "integrity": "sha512-9jTHuYe22TD3sNxy0nEIzC7ZrlRnDgeX3xPkbS7PnbdwYjl2o/z/YuCrRBwezdKpbTDTJ4VqIggzNyeRcKq3cg==", + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.10.0.tgz", + "integrity": "sha512-ZOkZd6a6t0BdKcWb0wAYHWQqCfdlN1PPnXOmg/XNrbo6gJhYWFX4qCNb6ahSn8TpAqBqLCoD4Q010F7GwOM7mA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "1.9.1", + "@puppeteer/browsers": "2.2.3", "cosmiconfig": "9.0.0", - "puppeteer-core": "21.11.0" + "devtools-protocol": "0.0.1286932", + "puppeteer-core": "22.10.0" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" }, "engines": { - "node": ">=16.13.2" + "node": ">=18" } }, "node_modules/puppeteer-core": { - "version": "21.11.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.11.0.tgz", - "integrity": "sha512-ArbnyA3U5SGHokEvkfWjW+O8hOxV1RSJxOgriX/3A4xZRqixt9ZFHD0yPgZQF05Qj0oAqi8H/7stDorjoHY90Q==", + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.10.0.tgz", + "integrity": "sha512-I54J4Vy4I07UHsgB1QSmuFoF7KNQjJWcvFBPhtY+ezMdBfwgGDr8dzYrJa11aPgP9kxIUHjhktcMmmfJkOAtTw==", "dev": true, "dependencies": { - "@puppeteer/browsers": "1.9.1", - "chromium-bidi": "0.5.8", - "cross-fetch": "4.0.0", + "@puppeteer/browsers": "2.2.3", + "chromium-bidi": "0.5.19", "debug": "4.3.4", - "devtools-protocol": "0.0.1232444", - "ws": "8.16.0" + "devtools-protocol": "0.0.1286932", + "ws": "8.17.0" }, "engines": { - "node": ">=16.13.2" + "node": ">=18" } }, "node_modules/qs": { @@ -3886,9 +3915,9 @@ } }, "node_modules/rollup": { - "version": "4.14.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz", - "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -3901,21 +3930,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.14.1", - "@rollup/rollup-android-arm64": "4.14.1", - "@rollup/rollup-darwin-arm64": "4.14.1", - "@rollup/rollup-darwin-x64": "4.14.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.14.1", - "@rollup/rollup-linux-arm64-gnu": "4.14.1", - "@rollup/rollup-linux-arm64-musl": "4.14.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1", - "@rollup/rollup-linux-riscv64-gnu": "4.14.1", - "@rollup/rollup-linux-s390x-gnu": "4.14.1", - "@rollup/rollup-linux-x64-gnu": "4.14.1", - "@rollup/rollup-linux-x64-musl": "4.14.1", - "@rollup/rollup-win32-arm64-msvc": "4.14.1", - "@rollup/rollup-win32-ia32-msvc": "4.14.1", - "@rollup/rollup-win32-x64-msvc": "4.14.1", + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", "fsevents": "~2.3.2" } }, @@ -3988,13 +4018,10 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4002,18 +4029,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -4159,24 +4174,24 @@ "dev": true }, "node_modules/servez": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/servez/-/servez-2.1.4.tgz", - "integrity": "sha512-HzbQCFVifpncMQ/HOJuPKBpqx229LY9qW8vzCRtAwitTB3aNAxbPx2oZtAXVjAiLf9UBJm3/SlnPQZvaNGJK0A==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/servez/-/servez-2.1.6.tgz", + "integrity": "sha512-0ftF6U5mfhHG/dJk6Lu6jglI83eSMazHdpdCcyGgEbEoT1GP7A/PSZxm1b2uo2BYKzP2Zq6hJnGR5e3EcDsSmA==", "dev": true, "dependencies": { "ansi-colors": "^4.1.1", "color-support": "^1.1.3", "commander": "^11.0.0", - "servez-lib": "^2.8.3" + "servez-lib": "^2.8.5" }, "bin": { "servez": "bin/servez" } }, "node_modules/servez-lib": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/servez-lib/-/servez-lib-2.8.3.tgz", - "integrity": "sha512-zz4t8ie1uSO24qsHqH/FoUgD6SqJs4tLjWHbYquSE44ZUKvOnfXN4lWsdpLHTGh2Pzte9HIWmYtTOw0L5nZUIw==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/servez-lib/-/servez-lib-2.8.5.tgz", + "integrity": "sha512-6QNqjCVX6t17CQfJfg6f1XtMtdWxXx2maqdrZ+uJYpCDUQinyeDicF4WR7G3hDUnTv2HTp/C9T8kE0aDOVObqw==", "dev": true, "dependencies": { "basic-auth": "^2.0.1", @@ -4283,9 +4298,9 @@ } }, "node_modules/socks": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.2.tgz", - "integrity": "sha512-5Hvyu6Md91ooZzdrN/bSn/zlulFaRHrk2/6IY6qQNa3oVHTiG+CKxBV5PynKCGf31ar+3/hyPvlHFAYaBEOa3A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, "dependencies": { "ip-address": "^9.0.5", @@ -4336,13 +4351,14 @@ } }, "node_modules/streamx": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", - "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" @@ -4411,14 +4427,17 @@ } }, "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", "dev": true, "dependencies": { - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/tar-stream": { @@ -4432,6 +4451,15 @@ "streamx": "^2.15.0" } }, + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4465,12 +4493,6 @@ "node": ">=0.6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -4484,9 +4506,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "dev": true }, "node_modules/type-check": { @@ -4650,22 +4672,6 @@ "resolved": "https://registry.npmjs.org/webgpu-utils/-/webgpu-utils-1.8.2.tgz", "integrity": "sha512-yf5Wix5CJtmTpR8iycasIJ2+8bw5cwmrkdV0O/oQId04+mZFMsEpR9gr1bT+2qYk0fDIAnxa3Jm+R8c+bA62nA==" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4711,9 +4717,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4809,6 +4815,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index 5e2098e..d0b1ee6 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,9 @@ "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-typescript": "^11.1.6", "@tsconfig/recommended": "^1.0.6", - "@typescript-eslint/eslint-plugin": "^7.6.0", - "@typescript-eslint/parser": "^7.6.0", - "@webgpu/types": "^0.1.40", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", + "@webgpu/types": "^0.1.42", "eslint": "^8.57.0", "eslint-plugin-html": "^7.1.0", "eslint-plugin-one-variable-per-var": "^0.0.3", @@ -53,10 +53,10 @@ "express": "^4.19.2", "markdown-it": "^13.0.2", "mocha": "^10.4.0", - "puppeteer": "^21.11.0", - "rollup": "^4.14.1", - "servez": "^2.1.4", - "tslib": "^2.6.2", + "puppeteer": "^22.10.0", + "rollup": "^4.18.0", + "servez": "^2.1.6", + "tslib": "^2.6.3", "typedoc": "^0.25.13", "typescript": "^5.4.5" }, diff --git a/src/command-encoder.ts b/src/command-encoder.ts index b0f06d3..4c6e6be 100644 --- a/src/command-encoder.ts +++ b/src/command-encoder.ts @@ -151,7 +151,7 @@ function validateB2TorT2BCopy(encoder: GPUCommandEncoder, buf: GPUImageCopyBuffe assert(device === s_objToDevice.get(tex.texture), 'texture is not from same device as commandEncoder', [tex.texture, encoder]); validateImageCopyBuffer(buf); - const [bufRequiredUsage, texRequiredUsage]: [keyof GPUBufferUsage, keyof GPUTextureUsage] = bufferIsSource + const [bufRequiredUsage, texRequiredUsage]: [keyof typeof GPUBufferUsage, keyof typeof GPUTextureUsage] = bufferIsSource ? ['COPY_SRC', 'COPY_DST'] : ['COPY_DST', 'COPY_SRC']; assert(!!(buf.buffer.usage & GPUBufferUsage[bufRequiredUsage]), () => `src.usage(${bufferUsageToString(buf.buffer.usage)} missing ${bufRequiredUsage})`, [buf.buffer]); diff --git a/test/js/utils.js b/test/js/utils.js index ed3b09b..f309767 100644 --- a/test/js/utils.js +++ b/test/js/utils.js @@ -1,3 +1,5 @@ +import {it} from '../mocha-support.js'; + function saveFunctionsOfClass(obj) { const desc = Object.getOwnPropertyDescriptors(obj); return Object.entries(desc) @@ -66,4 +68,13 @@ export async function expectValidationError(expectError, fn) { throw error; } } +} + +export function itWithDevice(desc, fn) { + it.call(this, desc, async () => { + const adapter = await navigator.gpu.requestAdapter(); + const device = await adapter.requestDevice(); + await fn.call(this, device); + device.destroy(); + }); } \ No newline at end of file diff --git a/test/tests/binding-mixin-tests.js b/test/tests/binding-mixin-tests.js index 8764eb4..eaed616 100644 --- a/test/tests/binding-mixin-tests.js +++ b/test/tests/binding-mixin-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; async function createBindGroup(device, buffer) { device = device || await (await navigator.gpu.requestAdapter()).requestDevice(); @@ -65,8 +65,7 @@ export function addBindingMixinTests({ describe('check errors on setBindGroup', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const pass = await makePass(device); const bindGroup = await createBindGroup(device); await expectValidationError(false, () => { @@ -74,8 +73,7 @@ export function addBindingMixinTests({ }); }); - it('fails if ended', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if ended', async (device) => { const pass = await makePass(device); const bindGroup = await createBindGroup(device); endPass(pass); @@ -84,16 +82,15 @@ export function addBindingMixinTests({ }); }); - it('bindGroup from different device', async () => { - const pass = await makePass(); + itWithDevice('bindGroup from different device', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroup(); await expectValidationError(true, () => { pass.setBindGroup(0, bindGroup); }); }); - it('index < 0', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('index < 0', async (device) => { const pass = await makePass(device); const bindGroup = await createBindGroup(device); await expectValidationError(true, () => { @@ -101,8 +98,7 @@ export function addBindingMixinTests({ }); }); - it('index > max', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('index > max', async (device) => { const pass = await makePass(device); const bindGroup = await createBindGroup(device); await expectValidationError(true, () => { @@ -110,8 +106,7 @@ export function addBindingMixinTests({ }); }); - it('fails if buffer destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer destroyed', async (device) => { const pass = await makePass(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.UNIFORM}); const bindGroup = await createBindGroup(device, buffer); @@ -122,45 +117,40 @@ export function addBindingMixinTests({ }); const addDynamicOffsetTests = (fn) => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const pass = await makePass(device); + itWithDevice('works', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroupWithDynamicOffsets(device); await expectValidationError(false, () => { pass.setBindGroup(0, bindGroup, ...fn([2048 - 1024, 1024 - 512])); }); }); - it('fails if wrong number of dynamic offsets', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const pass = await makePass(device); + itWithDevice('fails if wrong number of dynamic offsets', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroupWithDynamicOffsets(device); await expectValidationError('same number of dynamicOffsets', () => { pass.setBindGroup(0, bindGroup, ...fn([0, 0, 0])); }); }); - it('fails if dynamic offset out of range', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const pass = await makePass(device); + itWithDevice('fails if dynamic offset out of range', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroupWithDynamicOffsets(device); await expectValidationError('dynamic offset is out of range', () => { pass.setBindGroup(0, bindGroup, ...fn([2048, 0])); }); }); - it('fails if dynamic offset is not storage aligned', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const pass = await makePass(device); + itWithDevice('fails if dynamic offset is not storage aligned', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroupWithDynamicOffsets(device); await expectValidationError('device.limits.minStorageBufferOffsetAlignment', () => { pass.setBindGroup(0, bindGroup, ...fn([128, 0])); }); }); - it('fails if dynamic offset is not uniform aligned', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const pass = await makePass(device); + itWithDevice('fails if dynamic offset is not uniform aligned', async (device) => { + const pass = await makePass(device); const bindGroup = await createBindGroupWithDynamicOffsets(device); await expectValidationError('device.limits.minUniformBufferOffsetAlignment', () => { pass.setBindGroup(0, bindGroup, ...fn([0, 128])); @@ -332,8 +322,8 @@ export function addValidateBindGroupTests({ describe('auto layout', () => { - it('works with auto layout', async () => { - const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('works with auto layout', async (device) => { + const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup1); pass.setBindGroup(2, bindGroup2); @@ -343,8 +333,8 @@ export function addValidateBindGroupTests({ }); }); - it('fails if missing bindGroup', async () => { - const { pass, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('fails if missing bindGroup', async (device) => { + const { pass, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); pass.setBindGroup(1, bindGroup1); pass.setBindGroup(2, bindGroup2); @@ -353,8 +343,8 @@ export function addValidateBindGroupTests({ }); }); - it('fails if resource is destroyed', async () => { - const { pass, u01Buffer, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('fails if resource is destroyed', async (device) => { + const { pass, u01Buffer, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup1); pass.setBindGroup(2, bindGroup2); @@ -365,8 +355,8 @@ export function addValidateBindGroupTests({ }); }); - it('fails if layout is incompatible (auto layout)', async () => { - const { device, pass, bindGroup0, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('fails if layout is incompatible (auto layout)', async (device) => { + const { pass, bindGroup0, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); const { bindGroup1 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup1); @@ -377,8 +367,8 @@ export function addValidateBindGroupTests({ }); }); - it('works if layout is compatible (auto layout)', async () => { - const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('works if layout is compatible (auto layout)', async (device) => { + const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup2); // 2 and 1 are swapped but pass.setBindGroup(2, bindGroup1); // they should be compatible @@ -388,8 +378,8 @@ export function addValidateBindGroupTests({ }); }); - it('false if layout is incompatible (auto layout + manual bindGroupLayout)', async () => { - const { device, pass, bindGroup0, bindGroup1, u20Buffer } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline); + itWithDevice('false if layout is incompatible (auto layout + manual bindGroupLayout)', async (device) => { + const { pass, bindGroup0, bindGroup1, u20Buffer } = await createResourcesForAutoLayoutBindGroupTests(makePassAndPipeline, device); const bindGroupLayout = device.createBindGroupLayout({ entries: [ { @@ -418,8 +408,8 @@ export function addValidateBindGroupTests({ describe('explicit layout', () => { - it('works with explicit layout', async () => { - const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility }); + itWithDevice('works with explicit layout', async (device) => { + const { pass, bindGroup0, bindGroup1, bindGroup2 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility, device }); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup1); pass.setBindGroup(2, bindGroup2); @@ -429,8 +419,8 @@ export function addValidateBindGroupTests({ }); }); - it('works with different explicit layout if they are compatible', async () => { - const { device, pass, bindGroup0, bindGroup1 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility }); + itWithDevice('works with different explicit layout if they are compatible', async (device) => { + const { pass, bindGroup0, bindGroup1 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility, device }); const { bindGroup2 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, device, visibility }); pass.setBindGroup(0, bindGroup0); pass.setBindGroup(1, bindGroup1); @@ -441,8 +431,8 @@ export function addValidateBindGroupTests({ }); }); - it('fails with incompatible bindGroup', async () => { - const { pass, bindGroup1, bindGroup2 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility }); + itWithDevice('fails with incompatible bindGroup', async (device) => { + const { pass, bindGroup1, bindGroup2 } = await createResourcesForExplicitLayoutBindGroupTests({ makePassAndPipeline, visibility, device }); pass.setBindGroup(0, bindGroup1); // incompatible pass.setBindGroup(1, bindGroup1); pass.setBindGroup(2, bindGroup2); diff --git a/test/tests/canvas-context-tests.js b/test/tests/canvas-context-tests.js index 14e915e..a768e88 100644 --- a/test/tests/canvas-context-tests.js +++ b/test/tests/canvas-context-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; async function createCommandEncoder(device) { device = device || await (await navigator.gpu.requestAdapter()).requestDevice(); @@ -26,8 +26,7 @@ describe('test canvas context', () => { describe('test getCurrentTexture', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const context = new OffscreenCanvas(1, 1).getContext('webgpu'); context.configure({ device, diff --git a/test/tests/command-encoder-tests.js b/test/tests/command-encoder-tests.js index a020d5c..95797a4 100644 --- a/test/tests/command-encoder-tests.js +++ b/test/tests/command-encoder-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; import copyBufferToBufferTests from './command-encoder/copyBufferToBuffer-tests.js'; import copyBufferToTextureTests from './command-encoder/copyBufferToTexture-tests.js'; import copyTextureToBufferTests from './command-encoder/copyTextureToBuffer-tests.js'; @@ -14,16 +14,16 @@ describe('test command encoder', () => { describe('test finish', () => { - it('can not finish twice', async () => { - const encoder = await createCommandEncoder(); + itWithDevice('can not finish twice', async (device) => { + const encoder = await createCommandEncoder(device); encoder.finish(); await expectValidationError(true, async () => { encoder.finish(); }); }); - it('can not finish if locked', async () => { - const encoder = await createCommandEncoder(); + itWithDevice('can not finish if locked', async (device) => { + const encoder = await createCommandEncoder(device); encoder.beginComputePass(); await expectValidationError(true, async () => { encoder.finish(); @@ -34,8 +34,7 @@ describe('test command encoder', () => { describe('test clearBuffer', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); await expectValidationError(false, async () => { @@ -43,8 +42,7 @@ describe('test command encoder', () => { }); }); - it('fails if encoder is locked', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is locked', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); encoder.beginComputePass(); @@ -53,8 +51,7 @@ describe('test command encoder', () => { }); }); - it('fails if encoder is finished', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is finished', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); encoder.finish(); @@ -63,8 +60,7 @@ describe('test command encoder', () => { }); }); - it('fails if buffer is destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer is destroyed', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); buffer.destroy(); @@ -73,8 +69,7 @@ describe('test command encoder', () => { }); }); - it('fails if buffer is from a different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer is from a different device', async (device) => { const encoder = await createCommandEncoder(device); const device2 = await (await navigator.gpu.requestAdapter()).requestDevice(); const buffer = device2.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); @@ -83,8 +78,7 @@ describe('test command encoder', () => { }); }); - it('fails if buffer.usage missing COPY_DST', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer.usage missing COPY_DST', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); await expectValidationError(true, async () => { @@ -92,8 +86,7 @@ describe('test command encoder', () => { }); }); - it('fails if size is not multiple of 4', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if size is not multiple of 4', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); await expectValidationError(true, async () => { @@ -101,8 +94,7 @@ describe('test command encoder', () => { }); }); - it('fails if offset is not multiple of 4', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if offset is not multiple of 4', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); await expectValidationError(true, async () => { @@ -110,8 +102,7 @@ describe('test command encoder', () => { }); }); - it('fails if offset + size > buffer.size', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if offset + size > buffer.size', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_DST}); await expectValidationError(true, async () => { diff --git a/test/tests/command-encoder/copy-utils.js b/test/tests/command-encoder/copy-utils.js index 4c16e66..ed5f465 100644 --- a/test/tests/command-encoder/copy-utils.js +++ b/test/tests/command-encoder/copy-utils.js @@ -1,8 +1,8 @@ +import {it} from '../../mocha-support.js'; import { assertTruthy, } from '../../assert.js'; -import {it} from '../../mocha-support.js'; -import {expectValidationError, bufferUsageToString, textureUsageToString } from '../../js/utils.js'; +import {expectValidationError, bufferUsageToString, itWithDevice, textureUsageToString } from '../../js/utils.js'; export async function createCommandEncoder(device) { device = device || await (await navigator.gpu.requestAdapter()).requestDevice(); @@ -25,14 +25,21 @@ export async function createDeviceWith4x4Format16BytesPerPixel() { return { device, format }; } +export function itWithDevice4x4Format16BytesPerPixel(desc, fn) { + it.call(this, desc, async () => { + const { device, format } = await createDeviceWith4x4Format16BytesPerPixel(); + await fn.call(this, device, format); + device.destroy(); + }); +} + export function addCopyTests({ doTest, bufferUsage, textureUsage, }) { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -50,8 +57,7 @@ export function addCopyTests({ }); }); - it('fails if encoder is locked', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is locked', async (device) => { const encoder = await createCommandEncoder(device); encoder.beginComputePass(); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); @@ -70,8 +76,7 @@ export function addCopyTests({ }); }); - it('fails if encoder is finished', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is finished', async (device) => { const encoder = await createCommandEncoder(device); encoder.finish(); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); @@ -90,8 +95,7 @@ export function addCopyTests({ }); }); - it('fails if buffer is destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer is destroyed', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -110,8 +114,7 @@ export function addCopyTests({ }); }); - it('fails if buffer is from a different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer is from a different device', async (device) => { const encoder = await createCommandEncoder(device); const device2 = await (await navigator.gpu.requestAdapter()).requestDevice(); const buffer = device2.createBuffer({size: 2048, usage: bufferUsage}); @@ -130,8 +133,7 @@ export function addCopyTests({ }); }); - it('fails if texture is from a different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if texture is from a different device', async (device) => { const encoder = await createCommandEncoder(device); const device2 = await (await navigator.gpu.requestAdapter()).requestDevice(); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); @@ -150,8 +152,7 @@ export function addCopyTests({ }); }); - it('fails if bytesPerRow is not multiple of 256', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if bytesPerRow is not multiple of 256', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -169,8 +170,7 @@ export function addCopyTests({ }); }); - it(`fails if texture.usage does not include ${textureUsageToString(textureUsage)}`, async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice(`fails if texture.usage does not include ${textureUsageToString(textureUsage)}`, async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -188,8 +188,7 @@ export function addCopyTests({ }); }); - it(`fails if buffer.usage does not include ${bufferUsageToString(bufferUsage)}`, async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice(`fails if buffer.usage does not include ${bufferUsageToString(bufferUsage)}`, async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: GPUBufferUsage.UNIFORM}); const texture = device.createTexture({ @@ -207,8 +206,7 @@ export function addCopyTests({ }); }); - it('fails if sampleCount not 1', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if sampleCount not 1', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -227,8 +225,7 @@ export function addCopyTests({ }); }); - it('fails if depth and incorrect aspect', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if depth and incorrect aspect', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -246,8 +243,7 @@ export function addCopyTests({ }); }); - it('fails if stencil and incorrect aspect', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if stencil and incorrect aspect', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -265,8 +261,7 @@ export function addCopyTests({ }); }); - it('fails if not write copyable', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if not write copyable', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -284,8 +279,7 @@ export function addCopyTests({ }); }); - it('fails if origin.x + copySize.width > width', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if origin.x + copySize.width > width', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -303,8 +297,7 @@ export function addCopyTests({ }); }); - it('fails if origin.y + copySize.height > height', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if origin.y + copySize.height > height', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -322,8 +315,7 @@ export function addCopyTests({ }); }); - it('fails if origin.z + copySize.depthOrArrayLayers > depthOrArrayLayers', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if origin.z + copySize.depthOrArrayLayers > depthOrArrayLayers', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -341,8 +333,7 @@ export function addCopyTests({ }); }); - it('fails copySize.width not multiple of blockWidth', async () => { - const { device, format } = await createDeviceWith4x4Format16BytesPerPixel(); + itWithDevice4x4Format16BytesPerPixel('fails copySize.width not multiple of blockWidth', async (device, format) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -360,8 +351,7 @@ export function addCopyTests({ }); }); - it('fails copySize.height not multiple of blockHeight', async () => { - const { device, format } = await createDeviceWith4x4Format16BytesPerPixel(); + itWithDevice4x4Format16BytesPerPixel('fails copySize.height not multiple of blockHeight', async (device, format) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -379,8 +369,7 @@ export function addCopyTests({ }); }); - it('fails src offset is not multiple of blockSize in bytes', async () => { - const { device, format } = await createDeviceWith4x4Format16BytesPerPixel(); + itWithDevice4x4Format16BytesPerPixel('fails src offset is not multiple of blockSize in bytes', async (device, format) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -398,8 +387,7 @@ export function addCopyTests({ }); }); - it('fails copy.height > 1 and bytesPerRow not set', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails copy.height > 1 and bytesPerRow not set', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -417,8 +405,7 @@ export function addCopyTests({ }); }); - it('fails copy.height = 1 and copySize.depthOrArrayLayers > 1 and bytesPerRow not set', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails copy.height = 1 and copySize.depthOrArrayLayers > 1 and bytesPerRow not set', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -436,8 +423,7 @@ export function addCopyTests({ }); }); - it('fails copy.height = 1 and copySize.depthOrArrayLayers > 1 and rowsPerImage not set', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails copy.height = 1 and copySize.depthOrArrayLayers > 1 and rowsPerImage not set', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ @@ -455,8 +441,7 @@ export function addCopyTests({ }); }); - it('fails if buffer range out of bounds', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if buffer range out of bounds', async (device) => { const encoder = await createCommandEncoder(device); const buffer = device.createBuffer({size: 2048, usage: bufferUsage}); const texture = device.createTexture({ diff --git a/test/tests/command-encoder/copyBufferToBuffer-tests.js b/test/tests/command-encoder/copyBufferToBuffer-tests.js index a243d72..cbed95a 100644 --- a/test/tests/command-encoder/copyBufferToBuffer-tests.js +++ b/test/tests/command-encoder/copyBufferToBuffer-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../../mocha-support.js'; -import {expectValidationError} from '../../js/utils.js'; +import {describe} from '../../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../../js/utils.js'; async function createCommandEncoder(device) { device = device || await (await navigator.gpu.requestAdapter()).requestDevice(); @@ -9,8 +9,7 @@ async function createCommandEncoder(device) { export default function () { describe('test copyBufferToBuffer', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.COPY_DST}); @@ -19,8 +18,7 @@ export default function () { }); }); - it('fails if src not same device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if src not same device', async (device) => { const encoder = await createCommandEncoder(device); const device2 = await (await navigator.gpu.requestAdapter()).requestDevice(); const src = device2.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); @@ -30,8 +28,7 @@ export default function () { }); }); - it('fails if dst not same device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if dst not same device', async (device) => { const encoder = await createCommandEncoder(device); const device2 = await (await navigator.gpu.requestAdapter()).requestDevice(); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); @@ -41,8 +38,7 @@ export default function () { }); }); - it('fails if src = dst', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if src = dst', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST}); await expectValidationError(true, async () => { @@ -50,8 +46,7 @@ export default function () { }); }); - it('fails if src destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if src destroyed', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.COPY_DST}); @@ -61,8 +56,7 @@ export default function () { }); }); - it('fails if dst destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if dst destroyed', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.COPY_DST}); @@ -72,8 +66,7 @@ export default function () { }); }); - it('fails if src.usage missing COPY_SRC', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if src.usage missing COPY_SRC', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.UNIFORM}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.COPY_DST}); @@ -82,8 +75,7 @@ export default function () { }); }); - it('fails if dst.usage missing COPY_DST', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if dst.usage missing COPY_DST', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.UNIFORM}); @@ -100,9 +92,8 @@ export default function () { { size: 8, dstOffset: 1, desc: 'dstOffset not multiple of 4' }, ]; for (const {srcOffset = 0, dstOffset = 0, size = 16, desc} of tests) { - it(desc, async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - const encoder = await createCommandEncoder(device); + itWithDevice(desc, async (device) => { + const encoder = await createCommandEncoder(device); const src = device.createBuffer({size: 16, usage: GPUBufferUsage.COPY_SRC}); const dst = device.createBuffer({size: 32, usage: GPUBufferUsage.COPY_DST}); await expectValidationError(true, async () => { diff --git a/test/tests/command-encoder/copyTextureToTexture-tests.js b/test/tests/command-encoder/copyTextureToTexture-tests.js index bf0feb7..ced74f1 100644 --- a/test/tests/command-encoder/copyTextureToTexture-tests.js +++ b/test/tests/command-encoder/copyTextureToTexture-tests.js @@ -1,12 +1,11 @@ -import {describe, it} from '../../mocha-support.js'; -import {expectValidationError } from '../../js/utils.js'; -import {createCommandEncoder, createDeviceWith4x4Format16BytesPerPixel} from './copy-utils.js'; +import {describe} from '../../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../../js/utils.js'; +import {createCommandEncoder, createDeviceWith4x4Format16BytesPerPixel, itWithDevice4x4Format16BytesPerPixel} from './copy-utils.js'; export default function () { describe('test copyTextureToTexture', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_SRC }); const dst = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_DST }); @@ -19,8 +18,7 @@ export default function () { }); }); - it('fails if encoder is locked', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is locked', async (device) => { const encoder = await createCommandEncoder(device); encoder.beginComputePass(); const src = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_SRC }); @@ -34,8 +32,7 @@ export default function () { }); }); - it('fails if encoder is finished', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if encoder is finished', async (device) => { const encoder = await createCommandEncoder(device); encoder.finish(); const src = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_SRC }); @@ -49,8 +46,7 @@ export default function () { }); }); - it('fails if src sampleCount != dst sampleCount', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if src sampleCount != dst sampleCount', async (device) => { const encoder = await createCommandEncoder(device); const src = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_SRC }); const dst = device.createTexture({ format: 'rgba8unorm', size: [4, 4], usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT, sampleCount: 4 }); @@ -72,8 +68,7 @@ export default function () { ]; for (const {fail, origin, desc} of overlapTests) { - it(desc, async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice(desc, async (device) => { const encoder = await createCommandEncoder(device); const texture = device.createTexture({ format: 'rgba8unorm', size: [4, 4, 4], usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST }); await expectValidationError(fail, async () => { @@ -104,8 +99,7 @@ export default function () { ['src', 'dst'].forEach((sd, i) => { describe(sd, () => { for (const {options, destroy, usage, otherDevice, desc} of sdTests) { - it(desc.replaceAll('$', sd), async () => { - const { device, format } = await createDeviceWith4x4Format16BytesPerPixel(); + itWithDevice4x4Format16BytesPerPixel(desc.replaceAll('$', sd), async (device, format) => { const encoder = await createCommandEncoder(device); const usages = [GPUTextureUsage.COPY_SRC, GPUTextureUsage.COPY_DST]; if (usage) { diff --git a/test/tests/compute-pass-tests.js b/test/tests/compute-pass-tests.js index 9e652ff..b87d212 100644 --- a/test/tests/compute-pass-tests.js +++ b/test/tests/compute-pass-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; import {addValidateBindGroupTests} from './binding-mixin-tests.js'; import {addTimestampWriteTests} from './timestamp-tests.js'; @@ -56,8 +56,7 @@ describe('test compute pass encoder', () => { describe('check errors on beginComputePass', () => { - it('errors if 2 passes are started', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('errors if 2 passes are started', async (device) => { const encoder = await createCommandEncoder(device); await createComputePass(device, encoder); await expectValidationError(true, async () => { @@ -65,8 +64,8 @@ describe('test compute pass encoder', () => { }); }); - it('can not end twice', async () => { - const pass = await createComputePass(); + itWithDevice('can not end twice', async (device) => { + const pass = await createComputePass(device); pass.end(); await expectValidationError(true, async () => { pass.end(); @@ -83,16 +82,15 @@ describe('test compute pass encoder', () => { describe('check errors on setPipeline', () => { - it('pipeline from different device', async () => { - const pipeline = await createComputePipeline(); + itWithDevice('pipeline from different device', async (device) => { + const pipeline = await createComputePipeline(device); const pass = await createComputePass(); await expectValidationError(true, () => { pass.setPipeline(pipeline); }); }); - it('fails if ended', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if ended', async (device) => { const pipeline = await createComputePipeline(device); const pass = await createComputePass(device); pass.end(); @@ -112,8 +110,7 @@ describe('test compute pass encoder', () => { { expectError: true, args: [1, 1, 100000000] , desc: 'z too big' }, ]; for (const {expectError, args, desc} of tests) { - it(desc, async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice(desc, async (device) => { const pipeline = await createComputePipeline(device); const pass = await createComputePass(device); pass.setPipeline(pipeline); @@ -141,8 +138,7 @@ describe('test compute pass encoder', () => { describe('dispatchWorkgroupsIndirect', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const pipeline = await createComputePipeline(device); const indirectBuffer = device.createBuffer({size: 12, usage: GPUBufferUsage.INDIRECT}); const pass = await createComputePass(device); @@ -152,8 +148,7 @@ describe('test compute pass encoder', () => { }); }); - it('fails if indirectBuffer destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if indirectBuffer destroyed', async (device) => { const pipeline = await createComputePipeline(device); const indirectBuffer = device.createBuffer({size: 12, usage: GPUBufferUsage.INDIRECT}); const pass = await createComputePass(device); @@ -164,8 +159,7 @@ describe('test compute pass encoder', () => { }); }); - it('fails if indirect offset outside data', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if indirect offset outside data', async (device) => { const pipeline = await createComputePipeline(device); const indirectBuffer = device.createBuffer({size: 12, usage: GPUBufferUsage.INDIRECT}); const pass = await createComputePass(device); @@ -175,8 +169,7 @@ describe('test compute pass encoder', () => { }); }); - it('fails if indirect size too small', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if indirect size too small', async (device) => { const pipeline = await createComputePipeline(device); const indirectBuffer = device.createBuffer({size: 8, usage: GPUBufferUsage.INDIRECT}); const pass = await createComputePass(device); diff --git a/test/tests/device-tests.js b/test/tests/device-tests.js index 22ae8a2..102fb50 100644 --- a/test/tests/device-tests.js +++ b/test/tests/device-tests.js @@ -1,6 +1,6 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; async function createBindGroupLayout(device) { device = device || await (await navigator.gpu.requestAdapter()).requestDevice(); @@ -32,9 +32,7 @@ describe('test device', () => { describe('test createBindGroup', () => { - it('fails if resource buffer is destroyed', async () => { - - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if resource buffer is destroyed', async (device) => { const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.UNIFORM}); buffer.destroy(); await expectValidationError(true, async () => { @@ -44,7 +42,7 @@ describe('test device', () => { }); /* TODO: finish buffer tests - it('fails if size > buffer.size', async () => { + itWithDevice('fails if size > buffer.size', async (device) => { const device = await (await navigator.gpu.requestAdapter()).requestDevice(); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.UNIFORM}); @@ -61,7 +59,7 @@ describe('test device', () => { }); - it('fails if offset + size > buffer.size', async () => { + itWithDevice('fails if offset + size > buffer.size', async (device) => { const device = await (await navigator.gpu.requestAdapter()).requestDevice(); const buffer = device.createBuffer({size: 16, usage: GPUBufferUsage.UNIFORM}); diff --git a/test/tests/push-pop-error-tests.js b/test/tests/push-pop-error-tests.js index 32c60e7..33961cd 100644 --- a/test/tests/push-pop-error-tests.js +++ b/test/tests/push-pop-error-tests.js @@ -1,20 +1,17 @@ -import {describe, it} from '../mocha-support.js'; +import {describe} from '../mocha-support.js'; +import { itWithDevice } from '../js/utils.js'; import { assertFalsy, assertInstanceOf } from '../assert.js'; describe('test push/pop error scope', () => { - it('test we get error (because they are being captured)', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - + itWithDevice('test we get error (because they are being captured)', async (device) => { device.pushErrorScope('validation'); device.createSampler({maxAnisotropy: 0}); const err = await device.popErrorScope(); assertInstanceOf(err, GPUValidationError); }); - it('test we get errors nested', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - + itWithDevice('test we get errors nested', async (device) => { device.pushErrorScope('validation'); device.pushErrorScope('validation'); device.createSampler({maxAnisotropy: 0}); @@ -31,9 +28,7 @@ describe('test push/pop error scope', () => { assertFalsy(rootErr); }); - it('test we get errors nested - more', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - + itWithDevice('test we get errors nested - more', async (device) => { device.pushErrorScope('validation'); device.pushErrorScope('validation'); device.pushErrorScope('validation'); @@ -52,9 +47,7 @@ describe('test push/pop error scope', () => { assertInstanceOf(rootErr, GPUValidationError); }); - it('test we get uncaught errors', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); - + itWithDevice('test we get uncaught errors', async (device) => { const promise = new Promise(resolve => { device.addEventListener('uncapturederror', (e) => { resolve(e.error); diff --git a/test/tests/render-bundle-tests.js b/test/tests/render-bundle-tests.js index 74edd33..46c3abe 100644 --- a/test/tests/render-bundle-tests.js +++ b/test/tests/render-bundle-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; import {addBindingMixinTests} from './binding-mixin-tests.js'; import {addRenderMixinTests} from './render-mixin-tests.js'; @@ -65,16 +65,15 @@ describe('test render bundle encoder', () => { describe('check errors on setPipeline', () => { - it('pipeline from different device', async () => { - const pipeline = await createRenderPipeline(); + itWithDevice('pipeline from different device', async (device) => { + const pipeline = await createRenderPipeline(device); const pass = await createRenderPass(); await expectValidationError(true, () => { pass.setPipeline(pipeline); }); }); - it('fails if ended', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if ended', async (device) => { const pipeline = await createRenderPipeline(device); const pass = await createRenderPass(device); pass.end(); diff --git a/test/tests/render-mixin-tests.js b/test/tests/render-mixin-tests.js index 6872cba..216f075 100644 --- a/test/tests/render-mixin-tests.js +++ b/test/tests/render-mixin-tests.js @@ -1,5 +1,5 @@ -import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {describe} from '../mocha-support.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; import {addValidateBindGroupTests} from './binding-mixin-tests.js'; async function createRenderPipeline(device, { @@ -117,16 +117,15 @@ export function addRenderMixinTests({ describe('check errors on setPipeline', () => { - it('pipeline from different device', async () => { - const pipeline = await createRenderPipeline(); + itWithDevice('pipeline from different device', async (device) => { + const pipeline = await createRenderPipeline(device); const pass = await makePass(); await expectValidationError(true, () => { pass.setPipeline(pipeline); }); }); - it('fails if ended', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if ended', async (device) => { const pipeline = await createRenderPipeline(device); const pass = await makePass(device); endPass(pass); @@ -135,8 +134,7 @@ export function addRenderMixinTests({ }); }); - it('fails if pipeline colorFormats do not match', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if pipeline colorFormats do not match', async (device) => { const pipeline = await createRenderPipeline(device, {format: 'r8unorm'}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -144,8 +142,7 @@ export function addRenderMixinTests({ }); }); - it('fails if pipeline sampleCount does not match', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if pipeline sampleCount does not match', async (device) => { const pipeline = await createRenderPipeline(device, {sampleCount: 4}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -153,8 +150,7 @@ export function addRenderMixinTests({ }); }); - it('fails if pipeline depthStencilFormat does not match', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if pipeline depthStencilFormat does not match', async (device) => { const pipeline = await createRenderPipeline(device, {depthStencilFormat: 'depth24plus'}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -167,23 +163,22 @@ export function addRenderMixinTests({ describe('check errors on setVertexBuffer', () => { - it('works with null', async () => { - const pass = await makePass(); + itWithDevice('works with null', async (device) => { + const pass = await makePass(device); await expectValidationError(false, () => { pass.setVertexBuffer(0, null); }); }); - it('fails with null if ended', async () => { - const pass = await makePass(); + itWithDevice('fails with null if ended', async (device) => { + const pass = await makePass(device); endPass(pass); await expectValidationError(true, () => { pass.setVertexBuffer(0, null); }); }); - it('works with buffer', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works with buffer', async (device) => { const pass = await makePass(device); const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.VERTEX}); await expectValidationError(false, () => { @@ -191,8 +186,7 @@ export function addRenderMixinTests({ }); }); - it('errors if buffer is destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('errors if buffer is destroyed', async (device) => { const pass = await makePass(device); const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.VERTEX}); buffer.destroy(); @@ -201,39 +195,35 @@ export function addRenderMixinTests({ }); }); - it('slot < 0', async () => { - const pass = await makePass(); + itWithDevice('slot < 0', async (device) => { + const pass = await makePass(device); await expectValidationError(true, () => { pass.setVertexBuffer(-1, null); }); }); - it('slot > max', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('slot > max', async (device) => { const pass = await makePass(device); await expectValidationError(true, () => { pass.setVertexBuffer(device.limits.maxVertexBuffers, null); }); }); - it('offset is not multiple of 4', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset is not multiple of 4', async (device) => { const pass = await makePass(device); await expectValidationError(true, () => { pass.setVertexBuffer(0, null, 3); }); }); - it('offset + size > bufferSize (no buffer)', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset + size > bufferSize (no buffer)', async (device) => { const pass = await makePass(device); await expectValidationError(true, () => { pass.setVertexBuffer(0, null, 4); }); }); - it('offset + size > bufferSize (w/buffer via size)', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset + size > bufferSize (w/buffer via size)', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.VERTEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -241,8 +231,7 @@ export function addRenderMixinTests({ }); }); - it('offset + size > bufferSize (w/buffer via offset + size)', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset + size > bufferSize (w/buffer via offset + size)', async (device) => { const buffer = device.createBuffer({size: 8, usage: GPUBufferUsage.VERTEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -250,8 +239,7 @@ export function addRenderMixinTests({ }); }); - it('buffer from different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('buffer from different device', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.VERTEX}); const pass = await makePass(); await expectValidationError(true, () => { @@ -259,8 +247,7 @@ export function addRenderMixinTests({ }); }); - it('buffer not VERTEX', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('buffer not VERTEX', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -272,8 +259,7 @@ export function addRenderMixinTests({ describe('check errors on setIndexBuffer', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(false, () => { @@ -281,8 +267,7 @@ export function addRenderMixinTests({ }); }); - it('errors if buffer is destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('errors if buffer is destroyed', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); buffer.destroy(); const pass = await makePass(device); @@ -291,8 +276,7 @@ export function addRenderMixinTests({ }); }); - it('fails if ended', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if ended', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); endPass(pass); @@ -301,8 +285,7 @@ export function addRenderMixinTests({ }); }); - it('offset is not multiple of 2 when format is uint16', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset is not multiple of 2 when format is uint16', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -310,8 +293,7 @@ export function addRenderMixinTests({ }); }); - it('offset is not multiple of 4 when format is uint32', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset is not multiple of 4 when format is uint32', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -319,8 +301,7 @@ export function addRenderMixinTests({ }); }); - it('offset + size > buffer.size', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset + size > buffer.size', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -328,8 +309,7 @@ export function addRenderMixinTests({ }); }); - it('offset + size > buffer.size (offset + size)', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('offset + size > buffer.size (offset + size)', async (device) => { const buffer = device.createBuffer({size: 8, usage: GPUBufferUsage.INDEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -337,8 +317,7 @@ export function addRenderMixinTests({ }); }); - it('buffer from different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('buffer from different device', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.INDEX}); const pass = await makePass(); await expectValidationError(true, () => { @@ -346,8 +325,7 @@ export function addRenderMixinTests({ }); }); - it('buffer not INDEX', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('buffer not INDEX', async (device) => { const buffer = device.createBuffer({size: 4, usage: GPUBufferUsage.VERTEX}); const pass = await makePass(device); await expectValidationError(true, () => { @@ -359,8 +337,8 @@ export function addRenderMixinTests({ describe('check errors on draw', () => { - it('works', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('works', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -371,8 +349,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if pass ended', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if pass ended', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -383,8 +361,8 @@ export function addRenderMixinTests({ }); }); - it('fails if no pipeline', async () => { - const { device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if no pipeline', async (device) => { + const { vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setVertexBuffer(0, vertexBuffer0); pass.setVertexBuffer(1, vertexBuffer1); @@ -394,8 +372,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing vertexBuffer', async () => { - const { pipeline, device, vertexBuffer0 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing vertexBuffer', async (device) => { + const { pipeline, vertexBuffer0 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -405,8 +383,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if vertexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if vertexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -418,8 +396,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if vertexCount exceeds data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if vertexCount exceeds data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -431,8 +409,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if count exceeds data via binding size', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if count exceeds data via binding size', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0, 0, 20); @@ -443,8 +421,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if count exceeds data via binding offset', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if count exceeds data via binding offset', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0, 4); @@ -456,8 +434,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if instanceCount exceeds data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if instanceCount exceeds data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -486,8 +464,8 @@ export function addRenderMixinTests({ describe('check errors on drawIndexed', () => { - it('works', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('works', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -499,8 +477,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if pass ended', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if pass ended', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -512,8 +490,8 @@ export function addRenderMixinTests({ }); }); - it('fails if no pipeline', async () => { - const { device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if no pipeline', async (device) => { + const { vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setVertexBuffer(0, vertexBuffer0); pass.setVertexBuffer(1, vertexBuffer1); @@ -524,8 +502,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing vertexBuffer', async () => { - const { pipeline, device, vertexBuffer0, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing vertexBuffer', async (device) => { + const { pipeline, vertexBuffer0, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -536,8 +514,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if vertexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if vertexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -550,8 +528,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing indexBuffer', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing indexBuffer', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1 } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -562,8 +540,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -576,8 +554,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indexedCount > data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indexedCount > data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -589,8 +567,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indexedCount > data via size', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indexedCount > data via size', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -602,8 +580,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indexedCount > data via offset', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indexedCount > data via offset', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -615,8 +593,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if instanceCount > data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if instanceCount > data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -646,8 +624,8 @@ export function addRenderMixinTests({ describe('check errors on drawIndirect', () => { - it('works', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('works', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -658,8 +636,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if pass ended', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if pass ended', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -670,8 +648,8 @@ export function addRenderMixinTests({ }); }); - it('fails if no pipeline', async () => { - const { device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if no pipeline', async (device) => { + const { vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setVertexBuffer(0, vertexBuffer0); pass.setVertexBuffer(1, vertexBuffer1); @@ -681,8 +659,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing vertexBuffer', async () => { - const { pipeline, device, vertexBuffer0, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing vertexBuffer', async (device) => { + const { pipeline, vertexBuffer0, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -692,8 +670,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if vertexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if vertexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -705,8 +683,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indirectBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indirectBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -718,8 +696,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indirect offset outside data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indirect offset outside data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -751,8 +729,8 @@ export function addRenderMixinTests({ describe('check errors on drawIndexedIndirect', () => { - it('works', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('works', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -764,8 +742,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if pass ended', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if pass ended', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -777,8 +755,8 @@ export function addRenderMixinTests({ }); }); - it('fails if no pipeline', async () => { - const { device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if no pipeline', async (device) => { + const { vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setVertexBuffer(0, vertexBuffer0); pass.setVertexBuffer(1, vertexBuffer1); @@ -789,8 +767,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing vertexBuffer', async () => { - const { pipeline, device, vertexBuffer0, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing vertexBuffer', async (device) => { + const { pipeline, vertexBuffer0, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -801,8 +779,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if vertexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if vertexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -815,8 +793,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if missing indexBuffer', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if missing indexBuffer', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -827,8 +805,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indexBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indexBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -841,8 +819,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indirectBuffer destroyed', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indirectBuffer destroyed', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); @@ -855,8 +833,8 @@ export function addRenderMixinTests({ endPass(pass); }); - it('fails if indirect offset outside data', async () => { - const { pipeline, device, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(); + itWithDevice('fails if indirect offset outside data', async (device) => { + const { pipeline, vertexBuffer0, vertexBuffer1, indexBuffer, indirectBuffer } = await createRenderPipelineAndAttribResources(device); const pass = await makePass(device); pass.setPipeline(pipeline); pass.setVertexBuffer(0, vertexBuffer0); diff --git a/test/tests/render-pass-tests.js b/test/tests/render-pass-tests.js index 39692e4..0b10c05 100644 --- a/test/tests/render-pass-tests.js +++ b/test/tests/render-pass-tests.js @@ -1,5 +1,5 @@ import {describe, it} from '../mocha-support.js'; -import {expectValidationError} from '../js/utils.js'; +import {expectValidationError, itWithDevice} from '../js/utils.js'; import {addRenderMixinTests} from './render-mixin-tests.js'; import {addTimestampWriteTests, getDeviceWithTimestamp} from './timestamp-tests.js'; @@ -39,8 +39,7 @@ describe('test render pass encoder', () => { describe('check errors on beginRenderPass', () => { - it('errors if 2 passes are started', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('errors if 2 passes are started', async (device) => { const encoder = await createCommandEncoder(device); await createRenderPass(device, encoder); await expectValidationError(true, async () => { @@ -48,17 +47,15 @@ describe('test render pass encoder', () => { }); }); - it('can not end twice', async () => { - const pass = await createRenderPass(); + itWithDevice('can not end twice', async (device) => { + const pass = await createRenderPass(device); pass.end(); await expectValidationError(true, async () => { pass.end(); }); }); - it('errors when colorAttachments are not the same size', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when colorAttachments are not the same size', async (device) => { const textures = [2, 3].map(width => device.createTexture({ size: [width, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -77,9 +74,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when colorAttachments are not the same sampleCount', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when colorAttachments are not the same sampleCount', async (device) => { const textures = [1, 4].map(sampleCount => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -99,9 +94,7 @@ describe('test render pass encoder', () => { }); }); - it('works with resolveTarget', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('works with resolveTarget', async (device) => { const textures = [4, 1].map(sampleCount => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -124,9 +117,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when resolveTarget is not sampleCount 1', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when resolveTarget is not sampleCount 1', async (device) => { const textures = [4, 4].map(sampleCount => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -149,9 +140,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when resolveTarget is not same size', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when resolveTarget is not same size', async (device) => { const textures = [4, 1].map((sampleCount, i) => device.createTexture({ size: [3, 3 + i], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -174,9 +163,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when resolveTarget is not same format', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when resolveTarget is not same format', async (device) => { const textures = [4, 1].map((sampleCount, i) => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -198,9 +185,8 @@ describe('test render pass encoder', () => { }); }); }); - it('errors when no attachments', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + + itWithDevice('errors when no attachments', async (device) => { const encoder = device.createCommandEncoder(); await expectValidationError(true, () => { encoder.beginRenderPass({ @@ -209,9 +195,7 @@ describe('test render pass encoder', () => { }); }); - it('no error when max bytes per sample', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('no error when max bytes per sample', async (device) => { const textures = [1, 1, 1, 1].map(() => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -230,9 +214,7 @@ describe('test render pass encoder', () => { }); }); - it('error when > max bytes per sample', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('error when > max bytes per sample', async (device) => { const textures = new Array(Math.ceil(device.limits.maxColorAttachmentBytesPerSample / 16) + 1).fill(1).map(() => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -251,9 +233,7 @@ describe('test render pass encoder', () => { }); }); - it('error when > max attachments', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('error when > max attachments', async (device) => { const textures = new Array(device.limits.maxColorAttachments + 1).fill(1).map(() => device.createTexture({ size: [3, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -272,9 +252,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when depthStencilAttachment is a different size than the colorAttachments', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when depthStencilAttachment is a different size than the colorAttachments', async (device) => { const colorTexture = device.createTexture({ size: [2, 2], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -306,9 +284,7 @@ describe('test render pass encoder', () => { }); }); - it('fails when the sample layer/level is used more than once', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('fails when the sample layer/level is used more than once', async (device) => { const colorTexture = device.createTexture({ size: [2, 2], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -335,9 +311,7 @@ describe('test render pass encoder', () => { }); }); - it('passes when the sample different layers on the same texture', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('passes when the sample different layers on the same texture', async (device) => { const colorTexture = device.createTexture({ size: [2, 2, 2], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -364,9 +338,7 @@ describe('test render pass encoder', () => { }); }); - it('errors when colorAttachments are destroyed', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when colorAttachments are destroyed', async (device) => { const textures = [3, 3].map(width => device.createTexture({ size: [width, 3], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -384,12 +356,9 @@ describe('test render pass encoder', () => { })), }); }); - }); - it('errors when depthStencilAttachment is destroyed', async () => { - const adapter = await navigator.gpu.requestAdapter(); - const device = await adapter.requestDevice(); + itWithDevice('errors when depthStencilAttachment is destroyed', async (device) => { const colorTexture = device.createTexture({ size: [2, 2], usage: GPUTextureUsage.RENDER_ATTACHMENT, @@ -444,6 +413,7 @@ describe('test render pass encoder', () => { occlusionQuerySet, }); }); + device.destroy(); }); addTimestampWriteTests({ @@ -465,8 +435,7 @@ describe('test render pass encoder', () => { describe('check errors on executeBundles', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const pass = await createRenderPass(device); const bundleEncoder = device.createRenderBundleEncoder({ colorFormats: ['rgba8unorm'], @@ -479,8 +448,7 @@ describe('test render pass encoder', () => { }); - it('fails if bundle is from different device', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if bundle is from different device', async (device) => { const pass = await createRenderPass(); const bundleEncoder = device.createRenderBundleEncoder({ colorFormats: ['rgba8unorm'], @@ -493,8 +461,7 @@ describe('test render pass encoder', () => { }); - it('fails if bundle incompatible', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if bundle incompatible', async (device) => { const pass = await createRenderPass(device); const bundleEncoder = device.createRenderBundleEncoder({ colorFormats: ['r8unorm'], @@ -511,8 +478,7 @@ describe('test render pass encoder', () => { describe('beginOcclusionQuery', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -523,16 +489,14 @@ describe('test render pass encoder', () => { }); }); - it('fails if no occlusionQuerySet on pass', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if no occlusionQuerySet on pass', async (device) => { const pass = await createRenderPass(device); await expectValidationError(true, () => { pass.beginOcclusionQuery(0); }); }); - it('fails if querySet destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if querySet destroyed', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -544,8 +508,7 @@ describe('test render pass encoder', () => { }); }); - it('fails if queryIndex out of range', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if queryIndex out of range', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -556,8 +519,7 @@ describe('test render pass encoder', () => { }); }); - it('fails if query in progress', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if query in progress', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -569,8 +531,7 @@ describe('test render pass encoder', () => { }); }); - it('fails if queryIndex already used', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if queryIndex already used', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -587,8 +548,7 @@ describe('test render pass encoder', () => { describe('endOcclusionQuery', () => { - it('works', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('works', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -600,8 +560,7 @@ describe('test render pass encoder', () => { }); }); - it('fails if querySet destroyed', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if querySet destroyed', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -615,8 +574,7 @@ describe('test render pass encoder', () => { }); - it('fails if no query in progress', async () => { - const device = await (await navigator.gpu.requestAdapter()).requestDevice(); + itWithDevice('fails if no query in progress', async (device) => { const occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: 2 }); const pass = await createRenderPass(device, undefined, { occlusionQuerySet, @@ -648,8 +606,8 @@ describe('test render pass encoder', () => { ]; for (const {success, args, desc, end} of tests) { - it(desc, async () => { - const pass = await createRenderPass(); + itWithDevice(desc, async (device) => { + const pass = await createRenderPass(device); if (end) { pass.end(); } @@ -675,8 +633,8 @@ describe('test render pass encoder', () => { ]; for (const {success, args, desc, end} of tests) { - it(desc, async () => { - const pass = await createRenderPass(); + itWithDevice(desc, async (device) => { + const pass = await createRenderPass(device); if (end) { pass.end(); } diff --git a/test/tests/timestamp-tests.js b/test/tests/timestamp-tests.js index 308dff1..1720cc7 100644 --- a/test/tests/timestamp-tests.js +++ b/test/tests/timestamp-tests.js @@ -13,13 +13,28 @@ export async function getDeviceWithTimestamp(test) { }); } +async function itWithDeviceWithTimestamp(desc, fn) { + it.call(this, desc, async function () { + const adapter = await navigator.gpu.requestAdapter(); + if (!adapter.features.has('timestamp-query')) { + this.skip('timestamp-writes feature not available'); + return null; + } + const device = await adapter.requestDevice({ + requiredFeatures: ['timestamp-query'], + }); + + await fn.call(this, device); + device.destroy(); + return null; + }); +} export function addTimestampWriteTests({ makePass, }) { describe('timestampWrites', () => { - it('works', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('works', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); await expectValidationError(false, async () => { @@ -29,8 +44,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if query destroyed', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if query destroyed', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); querySet.destroy(); @@ -41,8 +55,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if query from different device', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if query from different device', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); const device2 = await getDeviceWithTimestamp(this); @@ -52,10 +65,11 @@ export function addTimestampWriteTests({ timestampWrites: { querySet, beginningOfPassWriteIndex: 0, endOfPassWriteIndex: 1 }, }); }); + + device2.destroy(); }); - it('fails if query wrong type', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if query wrong type', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'occlusion'}); await expectValidationError(true, async () => { @@ -65,8 +79,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if both begin and end not set', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if both begin and end not set', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); await expectValidationError(true, async () => { @@ -76,8 +89,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if begin === end', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if begin === end', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); await expectValidationError(true, async () => { @@ -87,8 +99,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if begin out of range', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if begin out of range', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); await expectValidationError(true, async () => { @@ -98,8 +109,7 @@ export function addTimestampWriteTests({ }); }); - it('fails if end out of range', async function () { - const device = await getDeviceWithTimestamp(this); + itWithDeviceWithTimestamp('fails if end out of range', async function (device) { const querySet = device.createQuerySet({count: 2, type: 'timestamp'}); await expectValidationError(true, async () => {